package com.iplant.aps.serviceimpl;

import com.alibaba.fastjson.JSON;
import com.iplant.aps.service.WMSService;
import com.iplant.aps.service.mesenum.*;
import com.iplant.aps.service.po.APIResult;
import com.iplant.aps.service.po.OutResult;
import com.iplant.aps.service.po.Pagination;
import com.iplant.aps.service.po.ServiceResult;
import com.iplant.aps.service.po.aps.*;
import com.iplant.aps.service.po.bfc.BFCMessage;
import com.iplant.aps.service.po.bms.BMSEmployee;
import com.iplant.aps.service.po.bpm.BPMTaskBase;
import com.iplant.aps.service.po.excel.ExcelData;
import com.iplant.aps.service.po.excel.ExcelLineData;
import com.iplant.aps.service.po.excel.ExcelSheetData;
import com.iplant.aps.service.po.excel.MyExcelSheet;
import com.iplant.aps.service.po.fmc.FMCWorkCharge;
import com.iplant.aps.service.po.fmc.FMCWorkspace;
import com.iplant.aps.service.po.ipt.IPTOutsourcingMaterial;
import com.iplant.aps.service.po.lfs.LFSOperationLog;
import com.iplant.aps.service.po.lfs.LFSWorkAreaStation;
import com.iplant.aps.service.po.mrp.MRPMaterialPlan;
import com.iplant.aps.service.po.mss.MSSBOM;
import com.iplant.aps.service.po.mss.MSSBOMItem;
import com.iplant.aps.service.po.mss.MSSMaterial;
import com.iplant.aps.service.po.oms.OMSOrder;
import com.iplant.aps.service.po.sfc.SFCBOMTask;
import com.iplant.aps.service.po.sfc.SFCBOMTaskItem;
import com.iplant.aps.service.po.sfc.SFCBatchBOMTaskBPM;
import com.iplant.aps.service.po.sfc.SFCBatchBOMTaskBPMItem;
import com.iplant.aps.service.po.tcm.TCMMaterialChangeItems;
import com.iplant.aps.service.po.tcm.TCMMaterialChangeLog;
import com.iplant.aps.service.po.tcm.TCMTechChangeNotice;
import com.iplant.aps.service.po.wms.*;
import com.iplant.aps.service.utils.CloneTool;
import com.iplant.aps.service.utils.Configuration;
import com.iplant.aps.service.utils.StringUtils;
import com.iplant.aps.serviceimpl.dao.BaseDAO;
import com.iplant.aps.serviceimpl.dao.aps.APSBOMItemDAO;
import com.iplant.aps.serviceimpl.dao.aps.APSTaskPartDAO;
import com.iplant.aps.serviceimpl.dao.aps.APSTaskStepDAO;
import com.iplant.aps.serviceimpl.dao.bfc.BFCMessageDAO;
import com.iplant.aps.serviceimpl.dao.ipt.IPTOutsourcingMaterialDAO;
import com.iplant.aps.serviceimpl.dao.mes.MESSystemConfigDAO;
import com.iplant.aps.serviceimpl.dao.mrp.MRPMaterialPlanDAO;
import com.iplant.aps.serviceimpl.dao.mss.MSSBOMItemDAO;
import com.iplant.aps.serviceimpl.dao.oms.OMSOrderDAO;
import com.iplant.aps.serviceimpl.dao.sfc.SFCBOMTaskDAO;
import com.iplant.aps.serviceimpl.dao.sfc.SFCBOMTaskItemDAO;
import com.iplant.aps.serviceimpl.dao.sfc.SFCBatchBOMTaskBPMDAO;
import com.iplant.aps.serviceimpl.dao.sfc.SFCTaskStepDAO;
import com.iplant.aps.serviceimpl.dao.tcm.TCMMaterialChangeItemsDAO;
import com.iplant.aps.serviceimpl.dao.wms.*;
import com.iplant.aps.serviceimpl.utils.MESServer;
import com.iplant.aps.serviceimpl.utils.aps.APSConstans;
import com.iplant.aps.serviceimpl.utils.aps.APSUtils;
import com.iplant.aps.serviceimpl.utils.sap.ZIF_MM_GET_WMS281_WSStub;
import com.iplant.aps.utils.Constants;
import com.iplant.aps.utils.QRCodeUtil;
import com.iplant.aps.utils.RemoteInvokeUtils;
import com.iplant.aps.utils.RetCode;
import com.iplant.aps.utils.aps.ExcelUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class WMSServiceImpl implements WMSService {

    private static final Logger logger = LoggerFactory.getLogger(WMSServiceImpl.class);

    public WMSServiceImpl() {
        super();
    }

    private static WMSService Instance;

    public static WMSService getInstance() {
        if (Instance == null)
            Instance = new WMSServiceImpl();
        return Instance;
    }

    @Override
    public APIResult MSS_QueryBOM(BMSEmployee wLoginUser, int wBOMID, String wBOMNo, int wRouteID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();

            wParms.put("bom_no", wBOMNo);
            wParms.put("bom_id", wBOMID);
            wParms.put("RouteID", wRouteID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Bom/Info?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_QueryBOMAll(BMSEmployee wLoginUser, String wName, String wBOMNo, int wWorkShopID, int wBOMType,
                                     int wProductID, int wStatus) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();

            wParms.put("bom_no", wBOMNo);
            wParms.put("bom_name", wBOMNo);
            wParms.put("workshop_id", wWorkShopID);
            wParms.put("type_id", wBOMType);
            wParms.put("ProductID", wProductID);
            wParms.put("status", wStatus);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName, StringUtils
                            .Format("api/Bom/All?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                                    wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);

        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_QueryUnitList(BMSEmployee wLoginUser) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Unit/All?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);

        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_QueryMaterialList(BMSEmployee wLoginUser, String wMaterialNo) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("material_no", wMaterialNo);
            wParms.put("material_name", "");
            wParms.put("type_id", -1);
            wParms.put("status", -1);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Material/All?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);

        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_SaveBOM(BMSEmployee wLoginUser, MSSBOM wMSSBOM) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("data", wMSSBOM);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Bom/Update?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_SaveBOMItem(BMSEmployee wLoginUser, MSSBOMItem wMSSBOMItem) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("data", wMSSBOMItem);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/BomItem/Update?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_SaveMaterial(BMSEmployee wLoginUser, MSSMaterial wMSSMaterial) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("data", wMSSMaterial);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Material/Update?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_QueryBOMItemAll(BMSEmployee wLoginUser, int wBOMID, int wLineID, int wProductID,
                                         int wCustomerID, int wPlaceID, int wPartPointID, int wBOMType,
                                         int wReplaceType, int wRouteID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();

            wParms.put("bom_id", wBOMID);
            wParms.put("RouteID", wRouteID);
            wParms.put("PlaceID", -1);
            wParms.put("LineID", -1);
            wParms.put("ProductID", -1);
            wParms.put("CustomerID", -1);
            wParms.put("ReplaceType", -1);
            wParms.put("BOMType", -1);
            wParms.put("PartPointID", -1);
            wParms.put("OutSourceType", -1);
            wParms.put("IsList", -1);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/BomItem/All?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_QueryBOMItemByID(BMSEmployee wLoginUser, int wBOMItemID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("id", wBOMItemID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/BomItem/Info?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult MSS_QueryMaterialByID(BMSEmployee wLoginUser, int wMaterialID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("material_id", wMaterialID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Material/Info?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult APS_SaveBOMItemList(BMSEmployee wLoginUser, List<APSBOMItem> wAPSBOMItemList) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("data", wAPSBOMItemList);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/APSBOM/Create?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult APS_OrderStart(BMSEmployee wLoginUser, int wLineID, int wProductID, int wCustomerID, int wOrderID,
                                    String wWBSNo, String wPartNo) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("LineID", wLineID);
            wParms.put("ProductID", wProductID);
            wParms.put("CustomerID", wCustomerID);
            wParms.put("OrderID", wOrderID);
            wParms.put("WBSNo", wWBSNo);
            wParms.put("PartNo", wPartNo);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/APSBOM/OrderStart?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult APS_BOMItemUpdate(BMSEmployee wLoginUser, APSBOMItem wAPSBOMItem) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("data", wAPSBOMItem);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/APSBOM/Update?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParms, HttpMethod.POST);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    public APIResult MSS_ConfigAll(BMSEmployee wLoginUser, String wPartConfigNo, String wPartConfigName, int wActive,
                                   String wProductNo, int wCustomerID, int wLineID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParms = new HashMap<>();
            wParms.put("PartConfigNo", wPartConfigNo);
            wParms.put("PartConfigName", wPartConfigName);
            wParms.put("Active", wActive);
            wParms.put("ProductNo", wProductNo);
            wParms.put("CustomerID", wCustomerID);
            wParms.put("LineID", wLineID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/MSSPart/ConfigAll?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParms, HttpMethod.GET);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSPickDemand>> WMS_QueryPickDemandList(BMSEmployee wLoginUser, String wOrderType,
                                                                      String wDemandNo, int wProductID, int wLineID,
                                                                      int wCustomerID, String wOrderID, int wPartID,
                                                                      int wStatus,
                                                                      String wMaterial, Calendar wStartTime,
                                                                      Calendar wEndTime, int wSourceType,
                                                                      int wSendStatus,
                                                                      Calendar wPreSendStartDate,
                                                                      Calendar wPreSendEndDate,
                                                                      Pagination wPagination, String wSourceTypeNot,
                                                                      String wOrderTypeNot, int wIsFinish) {
        ServiceResult<List<WMSPickDemand>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<Integer> wIDList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wMaterial)) {
                wIDList = WMSPickDemandItemDAO.getInstance().SelectDemandList(wLoginUser, wMaterial, wStartTime,
                        wEndTime, wErrorCode);
                if (wIDList.size() <= 0) {
                    return wResult;
                }
            }

            wResult.Result = WMSPickDemandDAO.getInstance().SelectListPro(wLoginUser, -1, wOrderType, wDemandNo,
                    wProductID, wLineID, wCustomerID, wOrderID, wPartID, wStatus, wStartTime, wEndTime, wIDList,
                    wSourceType, wSendStatus, wPreSendStartDate, wPreSendEndDate, wPagination, wSourceTypeNot,
                    wOrderTypeNot, wIsFinish,
                    wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSPickDemand> WMS_QueryPickDemand(BMSEmployee wLoginUser, int wDemandID, int wIsWaveNumber) {
        ServiceResult<WMSPickDemand> wResult = new ServiceResult<>();
        wResult.Result = new WMSPickDemand();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);

            // 波次信息关联查询
            if (StringUtils.isNotEmpty(wResult.Result.WaveNumber) && (wIsWaveNumber == 0 || wIsWaveNumber == 1)) {
                List<WMSPickDemand> wList = WMSPickDemandDAO.getInstance().SelectListByWaveNumber(wLoginUser,
                        wResult.Result.WaveNumber, wErrorCode);
                wList.removeIf(p -> p.ID == wResult.Result.ID);
                wResult.Result.RelaDemandNos = StringUtils.Join(",",
                        wList.stream().map(p -> p.DemandNo).distinct().collect(Collectors.toList()));
                wResult.Result.RelaPartNos = StringUtils.Join(",",
                        wList.stream().map(p -> p.PartNo).distinct().collect(Collectors.toList()));

                List<WMSPickDemandItem> wItemList = WMSPickDemandItemDAO.getInstance().SelectListByDemandIDList(
                        wLoginUser,
                        wList.stream().map(p -> p.ID).distinct().collect(Collectors.toList()), wErrorCode);
                for (WMSPickDemandItem wWMSPickDemandItem : wItemList) {
                    if (wResult.Result.ItemList.stream().anyMatch(p -> p.PartPointID == wWMSPickDemandItem.PartPointID
                            && p.MaterialNo.equals(wWMSPickDemandItem.MaterialNo))) {
                        WMSPickDemandItem wOldItem = wResult.Result.ItemList.stream()
                                .filter(p -> p.PartPointID == wWMSPickDemandItem.PartPointID
                                        && p.MaterialNo.equals(wWMSPickDemandItem.MaterialNo))
                                .findFirst().get();
                        wOldItem.FQTY += wWMSPickDemandItem.FQTY;
                        wOldItem.PickedNumber += wWMSPickDemandItem.PickedNumber;
                    } else {
                        wResult.Result.ItemList.add(wWMSPickDemandItem);
                    }
                }
            }

            for (WMSPickDemandItem wWMSPickDemandItem : wResult.Result.ItemList) {
                wWMSPickDemandItem.FQTY = new BigDecimal(wWMSPickDemandItem.FQTY)
                        .setScale(2, RoundingMode.HALF_UP).doubleValue();
                wWMSPickDemandItem.PickedNumber = new BigDecimal(wWMSPickDemandItem.PickedNumber)
                        .setScale(2, RoundingMode.HALF_UP).doubleValue();
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_TriggerPickDemandTask(BMSEmployee wLoginUser, int wOrderID, int wPartID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // 获取订单
            OMSOrder wOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wOrderID, wErrorCode);
            // 判断需求是否已提
            List<WMSPickDemand> wExsitList = WMSPickDemandDAO.getInstance().SelectList(wLoginUser, -1,
                    String.valueOf(WMSOrderType.LineOrder.getValue()), "", wOrder.ProductID, wOrder.LineID,
                    wOrder.CustomerID, String.valueOf(wOrder.ID), wPartID, -1, null, null, null, wErrorCode);
            if (wExsitList.size() > 0) {
                wResult.FaultCode += "提示：该订单该工位的领料需求已存在!";
                return wResult;
            }

            // ①查询工位周计划
            List<APSTaskPart> wTaskPartList = APSTaskPartDAO.getInstance().SelectList(wLoginUser, -1, wOrderID, -1, -1,
                    wPartID, 1, APSShiftPeriod.Week.getValue(), new ArrayList<>(Arrays.asList(2, 4, 5)), -1,
                    null, null, wErrorCode);
            if (wTaskPartList == null || wTaskPartList.size() <= 0) {
                wResult.FaultCode += "提示：该订单该工位的周计划未下达";
                return wResult;
            }
            // ②查询标准BOM
            int wBOMID = MSSBOMItemDAO.getInstance().QueryCurrentBOMID(wLoginUser, wOrderID, wErrorCode);


            if (wBOMID <= 0) {
                wResult.FaultCode += "提示：该订单无当前标准BOM";
                return wResult;
            }
            List<MSSBOMItem> wItemList = MSSBOMItemDAO.getInstance().SelectList(wLoginUser, wBOMID, -1, wPartID,
                    wErrorCode);
            if (wItemList == null || wItemList.size() <= 0) {
                wResult.FaultCode += "提示：该订单该工位无标准BOM";
                return wResult;
            }

            // 必换或委外必修
            wItemList = wItemList.stream().filter(p -> p.ReplaceType == 1 || p.OutsourceType == 1)
                    .collect(Collectors.toList());

            // ③创建领料需求单
            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            String wCode = WMSPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);
            Calendar wTime = wTaskPartList.get(0).StartTime;

            Calendar expectTime1 = Calendar.getInstance();
            expectTime1.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 0, 0, 0);

            Calendar expectTime2 = Calendar.getInstance();
            expectTime2.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 12, 0, 0);

            String monitorNo = "";
            String monitor = "";
            BMSEmployee wUser = WMSPickDemandDAO.getInstance().GetMonitorByPart(wLoginUser, wPartID, wErrorCode);
            if (StringUtils.isNotEmpty(wUser.LoginID)) {
                monitorNo = wUser.LoginID;
                monitor = wUser.Name;
            }

            List<Integer> wMaterialIDList = wItemList.stream().map(p -> p.MaterialID).distinct()
                    .collect(Collectors.toList());
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            Map<Integer, Double> wMaterialPackMap = MRPMaterialPlanDAO.getInstance().GetMaterialPackMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            // 获取反冲物料列表
            boolean wIsSendRecoilMaterial = Configuration.readConfigString("IsSendRecoilMaterial", "config/config")
                    .equals("1");

            WMSPickDemand wWMSPickDemand = new WMSPickDemand(0, "1900",
                    String.valueOf(WMSOrderType.LineOrder.getValue()), wCode, expectTime1, expectTime2, monitorNo,
                    monitor, wOrder.ProductID, wOrder.ProductNo, wOrder.LineID, wOrder.LineName, wOrder.CustomerID,
                    wOrder.Customer, APSConstans.GetCRMCustomer(wOrder.CustomerID).CustomerCode, wOrder.ID,
                    wOrder.PartNo, wPartID, APSConstans.GetFPCPartName(wPartID), APSConstans.GetFPCPart(wPartID).Code,
                    "", "", wBaseTime, "", "", wBaseTime, 1, wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(),
                    wOrder.OrderNo, wBaseTime);
            wWMSPickDemand.SourceType = WMSPickDemandSourceType.Plan.getValue();
            int wDemandID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wWMSPickDemand, wErrorCode);
            if (wDemandID <= 0) {
                wResult.FaultCode += "提示：产线工位领料需求单创建失败!";
                return wResult;
            }
            // ④创建领料需求单明细
            int wIndex = 1;
            for (MSSBOMItem wMSSBOMItem : wItemList) {

                double wFQTY = wMSSBOMItem.MaterialNumber;
                int wMaterialType = 0;
                if (wMaterialTypeMap.containsKey(wMSSBOMItem.MaterialID)) {
                    wMaterialType = wMaterialTypeMap.get(wMSSBOMItem.MaterialID);
                }
                // 根据最小包装计算需求
                if (wMaterialPackMap.containsKey(wMSSBOMItem.MaterialID)
                        && wMaterialType == MSSMaterialType.RecoilMaterial.getValue() && wIsSendRecoilMaterial) {
                    double wMinPack = wMaterialPackMap.get(wMSSBOMItem.MaterialID);
                    if (wMinPack > 0) {
                        int wAreaID = APSUtils.getInstance().GetAreaID(wMSSBOMItem.PlaceID);
                        wFQTY = WMSServiceImpl.getInstance().WMS_GetRealLLNumber(wLoginUser, wMinPack,
                                wMSSBOMItem.MaterialID, wMSSBOMItem.MaterialNumber, wAreaID, wErrorCode).Result;
                    }
                }

                WMSPickDemandItem wWMSPickDemandItem = new WMSPickDemandItem(0, wDemandID, wMSSBOMItem.MaterialID,
                        wMSSBOMItem.MaterialNo, wMSSBOMItem.MaterialName, wMSSBOMItem.MaterialNumber, wOrder.OrderNo,
                        wMSSBOMItem.PartPointID,
                        APSConstans.GetFPCPartPoint(wMSSBOMItem.PartPointID).Code.replace("PS-", ""),
                        APSConstans.GetFPCPartPointName(wMSSBOMItem.PartPointID), String.valueOf(wIndex), "",
                        wMSSBOMItem.ReplaceType, SFCReplaceType.getEnumType(wMSSBOMItem.ReplaceType).getLable(),
                        wMSSBOMItem.OutsourceType, SFCOutSourceType.getEnumType(wMSSBOMItem.OutsourceType).getLable(),
                        "", "", wBaseTime, wWMSPickDemand.PartID, 1, wMSSBOMItem.MaterialNumber, 0);
                wWMSPickDemandItem.FQTY = wFQTY;

                wWMSPickDemandItem.IsOriDis = wMSSBOMItem.OriginalType == 1 ? "是" : "否";

                int wItemID = WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem, wErrorCode);
                if (wItemID > 0 && wIsSendRecoilMaterial && wWMSPickDemandItem.FQTY == 0) {
                    WMSServiceImpl.getInstance().WMS_RecoilMaterialUse(wLoginUser, wItemID);
                }
                wIndex++;
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ManualPush(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);

            // 查询系统参数，判断是否需要更新台位
            String wUpdateStationIDs = MESSystemConfigDAO.getInstance().SelectValueByKey(wLoginUser,
                    "wms.update.station.ids", wErrorCode);
            List<Integer> wUpdateStationIDList = StringUtils.parseIntList(wUpdateStationIDs.split(","));
            if (wUpdateStationIDList.contains(wPickDemand.PartID)) {
                // 获取当前台车所在台位信息
                FMCWorkspace wFMCWorkspace = WMSPickDemandDAO.getInstance().FMC_GetFMCWorkspaceByPartNo(wLoginUser,
                        wPickDemand.PartNo, wErrorCode);
                if (StringUtils.isNotEmpty(wFMCWorkspace.Name)) {
                    wPickDemand.WorkSpaceID = wFMCWorkspace.ID;
                    wPickDemand.WorkSpaceCode = wFMCWorkspace.Code;
                    wPickDemand.WorkSpaceName = wFMCWorkspace.Name;
                }
            }

            OMSOrder wOMSOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wPickDemand.OrderID, wErrorCode);

            boolean wIsActiveRowHandOver = Configuration.readConfigString("IsActiveRowHandOver", "config/config")
                    .equals("1");

            // 保存状态的完工车配送单直接取消
            if (wPickDemand.Status == WMSPickDemandStatus.Saved.getValue() && wOMSOrder.Status >= 5) {
                wPickDemand.IsFinish = 1;
                wPickDemand.Remark = "完工车取消";
                wPickDemand.Status = WMSPickDemandStatus.Canceled.getValue();

                if (wIsActiveRowHandOver) {
                    wPickDemand.Status = WMSPickDemandStatusNew.Canceld.getValue();
                }

                WMSPickDemandDAO.getInstance().Update(wLoginUser, wPickDemand, wErrorCode);
                return wResult;
            }

            // 判断是否是完工车推送，且财务是否同意
            if (wPickDemand.IsFinish == 1 && wPickDemand.IsFinanceAgree != 1) {
                wResult.FaultCode += StringUtils.Format("提示：【{0}】已完工不允许领料，请联系财务开放!", wOMSOrder.PartNo);
                return wResult;
            }

            // 车辆是完工车，需要改为取消状态，不推送wms
            if (wPickDemand.IsFinish == 0 && wOMSOrder.Status >= 5) {
                wPickDemand.IsFinish = 1;
                wPickDemand.Remark = "完工车取消";
                wPickDemand.Status = WMSPickDemandStatus.Canceled.getValue();
                if (wIsActiveRowHandOver) {
                    wPickDemand.Status = WMSPickDemandStatusNew.Canceld.getValue();
                }
                WMSPickDemandDAO.getInstance().Update(wLoginUser, wPickDemand, wErrorCode);
                return wResult;
            }

            List<WMSLinePartLL> wHeaderList = new ArrayList<>();
            WMSLinePartLL wWMSLinePartLL = GetWMSLinePartLL(wPickDemand, false);

            // 判断子项是否存在，若不存在直接取消掉
            if (wWMSLinePartLL.details == null || wWMSLinePartLL.details.size() <= 0) {
                wPickDemand.Remark = "工艺变更空单取消";
                wPickDemand.Status = WMSPickDemandStatus.Canceled.getValue();
                if (wIsActiveRowHandOver) {
                    wPickDemand.Status = WMSPickDemandStatusNew.Canceld.getValue();
                }
                WMSPickDemandDAO.getInstance().Update(wLoginUser, wPickDemand, wErrorCode);
                return wResult;
            }

            wHeaderList.add(wWMSLinePartLL);
            WMSLinePartLLs wWMSLinePartLLs = new WMSLinePartLLs(wHeaderList);

            WMSReturn wReturn = MyHelperServiceImpl.getInstance().WMS_PostLL(wWMSLinePartLLs, wPickDemand);
            if (wReturn.returnFlag.equals("1")) {
                wPickDemand.Status = WMSPickDemandStatus.Sended.getValue();
                if (wIsActiveRowHandOver) {
                    wPickDemand.Status = WMSPickDemandStatusNew.NotStart.getValue();
                    // 明细行状态更新为待分拣
                    for (WMSPickDemandItem wWMSPickDemandItem : wPickDemand.ItemList) {
                        wWMSPickDemandItem.Status = WMSPickDemandItemStatusNew.Sended.getValue();
                        WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem, wErrorCode);
                    }
                }
                wPickDemand.SendStatus = 1;
                wPickDemand.SendDesc = "推送成功";

                // 增加配送单手动推送成功的操作日志
                LFSOperationLog wLFSOperationLog = new LFSOperationLog(0, wDemandID,
                        LFSOperationLogType.PickDemandSend.getValue(),
                        LFSOperationLogType.PickDemandSend.getLable(),
                        wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(),
                        StringUtils.Format("手动推送配送单【{0}】成功", wPickDemand.DemandNo));
                LFSServiceImpl.getInstance().LFS_UpdateOperationLog(wLoginUser, wLFSOperationLog);
            } else {
                wPickDemand.SendStatus = 2;

                if (StringUtils.isEmpty(wReturn.returnDesc))
                    wPickDemand.SendDesc = "网络错误";
                else
                    wPickDemand.SendDesc = JSON.toJSONString(wReturn.resultInfo);

                wResult.FaultCode += wReturn.returnDesc;

                // 增加配送单手动推送失败的操作日志
                LFSOperationLog wLFSOperationLog = new LFSOperationLog(0, wDemandID,
                        LFSOperationLogType.PickDemandSend.getValue(),
                        LFSOperationLogType.PickDemandSend.getLable(),
                        wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(),
                        StringUtils.Format("手动推送配送单【{0}】失败，{1}", wPickDemand.DemandNo, wPickDemand.SendDesc));
                LFSServiceImpl.getInstance().LFS_UpdateOperationLog(wLoginUser, wLFSOperationLog);
            }

            WMSPickDemandDAO.getInstance().Update(wLoginUser, wPickDemand, wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 将MES配送单转换为WMS领料单
     */
    private WMSLinePartLL GetWMSLinePartLL(WMSPickDemand wPickDemand, boolean wIsUpdateWorkspace) {
        WMSLinePartLL wResult = new WMSLinePartLL();
        try {
            wResult.warehouseId = "WH01";
            wResult.customerId = wPickDemand.Factory;
            wResult.orderType = wPickDemand.OrderType;
            wResult.docNo = wPickDemand.DemandNo;
            wResult.expectedShipmentTime1 = wPickDemand.ExpectTime1Text;
            wResult.requiredDeliveryTime = wPickDemand.ExpectTime2Text;
            wResult.consigneeId = wPickDemand.MonitorNo;
            wResult.consigneeName = wPickDemand.Monitor;
            wResult.hedi01 = wPickDemand.ProductNo;
            wResult.hedi02 = wPickDemand.LineName;
            wResult.hedi03 = wPickDemand.CustomerCode;
            wResult.hedi04 = wPickDemand.PartNo;
            wResult.hedi05 = wPickDemand.PartName;
            wResult.hedi06 = wPickDemand.PartCode;
            wResult.hedi07 = wPickDemand.WBSNo;
            wResult.hedi08 = String.valueOf(wPickDemand.OrderID);
            wResult.hedi11 = WMSPickDemandSourceType.getEnumType(wPickDemand.SourceType).getLabel();
            wResult.hedi12 = wPickDemand.WorkSpaceName;
            // wResult.hedi09 = wPickDemand.ParentDemandNo;
            // 更新台位
            if (wIsUpdateWorkspace) {
                wResult.hedi13 = "TWUPD";
            }
            wResult.details = new ArrayList<>();

            int wBOMType = 0;
            String wDeleteID = "";
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            int wOriFlag = 0;
            for (WMSPickDemandItem wWMSPickDemandItem : wPickDemand.ItemList) {
                // 过滤掉需求为0的反冲料，先不发布
                if (wWMSPickDemandItem.FQTY <= 0) {
                    continue;
                }

                if (wWMSPickDemandItem.BOMItemNum > 0) {
                    List<APSBOMItem> apsbomItems = APSBOMItemDAO.getInstance().APS_QueryBOMItemList(BaseDAO.SysAdmin,
                            -1, wPickDemand.OrderID, "",
                            "", -1, -1, -1, wWMSPickDemandItem.PartID, wWMSPickDemandItem.PartPointID,
                            wWMSPickDemandItem.MaterialID, "", -1, -1, -1, null, -1, -1, -1, wErrorCode);
                    if (apsbomItems != null && apsbomItems.size() > 0) {
                        // BOM类型
                        wBOMType = apsbomItems.get(0).BOMType;
                        // 原车原装标识
                        wOriFlag = apsbomItems.get(0).OriginalType;

                        // 台车BOM删除标记
                        if (apsbomItems.stream().anyMatch(p -> p.OrderNum == wWMSPickDemandItem.BOMItemNum)) {
                            wDeleteID = apsbomItems.stream().filter(p -> p.OrderNum == wWMSPickDemandItem.BOMItemNum)
                                    .findFirst().get().DeleteID;
                        }
                        if (wDeleteID.equals("X") && apsbomItems.stream().anyMatch(p -> p.DeleteID.equals(""))) {
                            wWMSPickDemandItem.BOMItemNum = apsbomItems.stream().filter(p -> p.DeleteID.equals(""))
                                    .findFirst().get().OrderNum;
                            wDeleteID = "";
                            WMSPickDemandItemDAO.getInstance().Update(BaseDAO.SysAdmin, wWMSPickDemandItem, wErrorCode);
                        }
                    }
                }

                WMSLLDetail wWMSLLDetail = new WMSLLDetail();
                wWMSLLDetail.sku = wWMSPickDemandItem.MaterialNo;
                wWMSLLDetail.qtyOrdered = StringUtils.parseString(wWMSPickDemandItem.FQTY);
                wWMSLLDetail.lotAtt08 = wPickDemand.WBSNo;
                // 截断
                if (wPickDemand.WBSNo.length() > 9) {
                    wWMSLLDetail.lotAtt08 = wPickDemand.WBSNo.substring(0, 9);
                }
                // 偶换件给空
                if (wWMSPickDemandItem.ReplaceType == 2) {
                    wWMSLLDetail.lotAtt08 = "";
                }
                wWMSLLDetail.lotAtt11 = wWMSPickDemandItem.AssessmentType;
                wWMSLLDetail.dedi01 = wWMSPickDemandItem.PartPointCode;
                wWMSLLDetail.dedi02 = wWMSPickDemandItem.PartPointName;
                wWMSLLDetail.dedi03 = wWMSPickDemandItem.RowNo;
                wWMSLLDetail.userDefine1 = wWMSPickDemandItem.GroupFlag;
                wWMSLLDetail.userDefine2 = wWMSPickDemandItem.KittingFlag;
                wWMSLLDetail.dedi11 = String.valueOf(wWMSPickDemandItem.BOMItemNum);
                wWMSLLDetail.dedi12 = String.valueOf(wBOMType);
                wWMSLLDetail.dedi13 = wDeleteID;
                if (wOriFlag > 0) {
                    wWMSLLDetail.lotAtt14 = wPickDemand.PartNo;
                }
                wResult.details.add(wWMSLLDetail);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    private WMSLinePartLL GetWMSLinePartLL_Update(WMSPickDemand wPickDemand) {
        WMSLinePartLL wResult = new WMSLinePartLL();
        try {
            wResult.warehouseId = "WH01";
            wResult.customerId = wPickDemand.Factory;
            wResult.orderType = wPickDemand.OrderType;
            wResult.docNo = wPickDemand.DemandNo;
            wResult.expectedShipmentTime1 = wPickDemand.ExpectTime1Text;
            wResult.requiredDeliveryTime = wPickDemand.ExpectTime2Text;
            wResult.consigneeId = wPickDemand.MonitorNo;
            wResult.consigneeName = wPickDemand.Monitor;
            wResult.hedi01 = wPickDemand.ProductNo;
            wResult.hedi02 = wPickDemand.LineName;
            wResult.hedi03 = wPickDemand.CustomerCode;
            wResult.hedi04 = wPickDemand.PartNo;
            wResult.hedi05 = wPickDemand.PartName;
            wResult.hedi06 = wPickDemand.PartCode;
            wResult.hedi07 = wPickDemand.WBSNo;
            wResult.hedi08 = String.valueOf(wPickDemand.OrderID);
            wResult.hedi11 = WMSPickDemandSourceType.getEnumType(wPickDemand.SourceType).getLabel();
            // wResult.hedi09 = wPickDemand.ParentDemandNo;
            wResult.details = new ArrayList<>();

            int wBOMType = 0;
            String wDeleteID = "";
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);
            for (WMSPickDemandItem wWMSPickDemandItem : wPickDemand.ItemList) {
                if (wWMSPickDemandItem.BOMItemNum > 0) {
                    List<APSBOMItem> apsbomItems = APSBOMItemDAO.getInstance().APS_QueryBOMItemList(BaseDAO.SysAdmin,
                            -1, wPickDemand.OrderID, "",
                            "", -1, -1, -1, wWMSPickDemandItem.PartID, wWMSPickDemandItem.PartPointID,
                            wWMSPickDemandItem.MaterialID, "", -1, -1, -1, null, -1, -1, -1, wErrorCode);
                    if (apsbomItems != null && apsbomItems.size() > 0) {
                        // BOM类型
                        wBOMType = apsbomItems.get(0).BOMType;
                        // 台车BOM删除标记
                        if (apsbomItems.stream().anyMatch(p -> p.OrderNum == wWMSPickDemandItem.BOMItemNum)) {
                            wDeleteID = apsbomItems.stream().filter(p -> p.OrderNum == wWMSPickDemandItem.BOMItemNum)
                                    .findFirst().get().DeleteID;
                        }
                    }
                }

                WMSLLDetail wWMSLLDetail = new WMSLLDetail();
                wWMSLLDetail.sku = wWMSPickDemandItem.MaterialNo;
                wWMSLLDetail.qtyOrdered = StringUtils.parseString(wWMSPickDemandItem.FQTY);

                // 判断如果是完工关闭，则推送0
                if (wWMSPickDemandItem.Status == WMSPickDemandItemStatusNew.FinishedClose.getValue()
                        || wWMSPickDemandItem.DeleteFlag == 1) {
                    wWMSLLDetail.qtyOrdered = "0";
                }

                wWMSLLDetail.lotAtt08 = wPickDemand.WBSNo;
                // 截断
                if (wPickDemand.WBSNo.length() > 9) {
                    wWMSLLDetail.lotAtt08 = wPickDemand.WBSNo.substring(0, 9);
                }
                // 偶换件给空
                if (wWMSPickDemandItem.ReplaceType == 2) {
                    wWMSLLDetail.lotAtt08 = "";
                }
                wWMSLLDetail.lotAtt11 = wWMSPickDemandItem.AssessmentType;
                wWMSLLDetail.dedi01 = wWMSPickDemandItem.PartPointCode;
                wWMSLLDetail.dedi02 = wWMSPickDemandItem.PartPointName;
                wWMSLLDetail.dedi03 = wWMSPickDemandItem.RowNo;
                wWMSLLDetail.userDefine1 = wWMSPickDemandItem.GroupFlag;
                wWMSLLDetail.userDefine2 = wWMSPickDemandItem.KittingFlag;
                wWMSLLDetail.dedi11 = String.valueOf(wWMSPickDemandItem.BOMItemNum);
                wWMSLLDetail.dedi12 = String.valueOf(wBOMType);
                wWMSLLDetail.dedi13 = wDeleteID;
                wResult.details.add(wWMSLLDetail);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 将MES批量偶换件配送单转换为WMS领料单
     */
    private WMSLinePartLL GetWMSLinePartLL(WMSBatchPickDemand wPickDemand) {
        WMSLinePartLL wResult = new WMSLinePartLL();
        try {
            wResult.warehouseId = "WH01";
            wResult.customerId = wPickDemand.Factory;
            wResult.orderType = wPickDemand.OrderType;
            wResult.docNo = wPickDemand.DemandNo;
            wResult.expectedShipmentTime1 = wPickDemand.ExpectTime1Text;
            wResult.requiredDeliveryTime = wPickDemand.ExpectTime2Text;
            wResult.hedi01 = wPickDemand.ProductNo;
            wResult.hedi02 = wPickDemand.LineName;
            wResult.hedi09 = "";
            wResult.hedi11 = WMSPickDemandSourceType.getEnumType(wPickDemand.SourceType).getLabel();
            wResult.details = new ArrayList<>();
            for (WMSBatchPickDemandItem wWMSPickDemandItem : wPickDemand.ItemList) {
                WMSLLDetail wWMSLLDetail = new WMSLLDetail();
                wWMSLLDetail.sku = wWMSPickDemandItem.MaterialNo;
                wWMSLLDetail.qtyOrdered = StringUtils.parseString(wWMSPickDemandItem.FQTY);
                // 偶换件给空
                wWMSLLDetail.lotAtt08 = "";
                wWMSLLDetail.lotAtt11 = wWMSPickDemandItem.AssessmentType;
                wWMSLLDetail.dedi03 = wWMSPickDemandItem.RowNo;
                wWMSLLDetail.userDefine1 = wWMSPickDemandItem.GroupFlag;
                wWMSLLDetail.userDefine2 = wWMSPickDemandItem.KittingFlag;
                wResult.details.add(wWMSLLDetail);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_Sorting(BMSEmployee wLoginUser, int wDemandID, int wStatus, String wLoginID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            BMSEmployee wUser = null;
            if (StringUtils.isNotEmpty(wLoginID)) {
                List<BMSEmployee> wUserList = APSConstans.GetBMSEmployeeList().values().stream()
                        .filter(p -> p.LoginID.equals(wLoginID)).collect(Collectors.toList());
                if (wUserList.size() <= 0) {
                    wResult.FaultCode += "提示：二维码格式错误，用户不存在!";
                    return wResult;
                }
                wUser = wUserList.get(0);
            }

            WMSPickDemand wItem = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);
            if (wItem == null || wItem.ID <= 0) {
                return wResult;
            }

            switch (WMSPickDemandStatus.getEnumType(wStatus)) {
                case Sended:// 分拣
                    wItem.Status = WMSPickDemandStatus.Picked.getValue();
                    wItem.SorterID = wLoginUser.ID;
                    wItem.Sorter = wLoginUser.Name;
                    wItem.SorterNo = wLoginUser.LoginID;
                    wItem.SorterTime = Calendar.getInstance();

                    ExecutorService wES = Executors.newFixedThreadPool(1);
                    wES.submit(() -> WMS_Sorting_SendMessage(wLoginUser, wItem));
                    wES.shutdown();
                    break;
                case Picked:// 交接
                    wItem.Status = WMSPickDemandStatus.Checked.getValue();
                    wItem.DeliveryID = wLoginUser.ID;
                    wItem.DeliveryMan = wLoginUser.Name;
                    wItem.DeliveryNo = wLoginUser.LoginID;
                    wItem.DeliveryTime = Calendar.getInstance();

                    ExecutorService wES1 = Executors.newFixedThreadPool(1);
                    wES1.submit(() -> {
                        WMS_Sorting_CloseMessage(wLoginUser, wItem);
                        WMS_Sorting_SendMessage(wLoginUser, wItem);
                        // 执行退料
                        // WMS_BackMaterial_Run(wLoginUser, wItem);
                    });
                    wES1.shutdown();

                    break;
                case Checked:// 配送
                    wItem.Status = WMSPickDemandStatus.Received.getValue();
                    wItem.ReceiveTime = Calendar.getInstance();
                    if (wUser == null) {
                        wItem.ReceiveID = wLoginUser.ID;
                        wItem.ReceiveMan = wLoginUser.Name;
                        wItem.ReceiveNo = wLoginUser.LoginID;
                    } else {
                        wItem.ReceiveID = wUser.ID;
                        wItem.ReceiveMan = wUser.Name;
                        wItem.ReceiveNo = wUser.LoginID;
                    }

                    ExecutorService wES2 = Executors.newFixedThreadPool(1);
                    wES2.submit(() -> {
                        // 配送后，关闭待办消息
                        WMS_Sorting_CloseMessage(wLoginUser, wItem);
                        // 配送后，维护配送条目的日计划
                        WMS_Sorting_MaintainTaskStep(wLoginUser, wItem);
                        // 执行退料
                        // WMS_BackMaterial_Run(wLoginUser, wItem);
                        // 线边库维护
                        WMS_UpdateLineLibrary(wLoginUser, wItem);
                    });
                    wES2.shutdown();
                    break;
                default:
                    break;
            }

            WMSPickDemandDAO.getInstance().Update(wLoginUser, wItem, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 线边库库存维护
     */
    private void WMS_UpdateLineLibrary(BMSEmployee wLoginUser, WMSPickDemand wItem) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // 工区工位
            List<LFSWorkAreaStation> wLFSWorkAreaStationList = LFSServiceImpl.getInstance()
                    .LFS_QueryAreaDepartmentList(wLoginUser).List(LFSWorkAreaStation.class);
            if (wLFSWorkAreaStationList == null || wLFSWorkAreaStationList.size() <= 0) {
                return;
            }
            wLFSWorkAreaStationList = wLFSWorkAreaStationList.stream().filter(p -> p.Active == 1 && p.WorkAreaID > 0)
                    .collect(Collectors.toList());
            if (wLFSWorkAreaStationList.stream().noneMatch(p -> p.StationID == wItem.PartID)) {
                return;
            }

            int wAreaID = wLFSWorkAreaStationList.stream().filter(p -> p.StationID == wItem.PartID).findFirst()
                    .get().WorkAreaID;

            for (WMSPickDemandItem wWMSPickDemandItem : wItem.ItemList) {
                if (wWMSPickDemandItem.MaterialType != MSSMaterialType.RecoilMaterial.getValue()) {
                    continue;
                }

                List<WMSLineEdgeLibrary> wList = WMSLineEdgeLibraryDAO.getInstance().SelectList(wLoginUser, -1,
                        wWMSPickDemandItem.MaterialID, "", null, null, wAreaID, 1, wWMSPickDemandItem.BatchNumber,
                        wErrorCode);
                if (wList.size() > 0) {
                    WMSLineEdgeLibrary wWMSLineEdgeLibrary = wList.get(0);
                    wWMSLineEdgeLibrary.Total += wWMSPickDemandItem.FQTY;
                    wWMSLineEdgeLibrary.FQTY += wWMSPickDemandItem.FQTY;
                    wWMSLineEdgeLibrary.EditTime = Calendar.getInstance();
                    WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                } else {
                    Calendar wBaseTime = Calendar.getInstance();
                    wBaseTime.set(2000, 0, 1, 0, 0, 0);
                    WMSLineEdgeLibrary wM = WMSLineEdgeLibraryDAO.getInstance().GetMaterialInfo(wLoginUser,
                            wWMSPickDemandItem.MaterialID, wErrorCode);

                    WMSLineEdgeLibrary wWMSLineEdgeLibrary = new WMSLineEdgeLibrary(0, wWMSPickDemandItem.MaterialID,
                            wWMSPickDemandItem.MaterialName, wWMSPickDemandItem.MaterialNo, wWMSPickDemandItem.FQTY,
                            wM.UnitID, "", wM.MinPacking, Calendar.getInstance(), "", wBaseTime, "",
                            wWMSPickDemandItem.FQTY, wWMSPickDemandItem.BatchNumber, wWMSPickDemandItem.Stock,
                            wWMSPickDemandItem.Supplier, wWMSPickDemandItem.ProductName, wWMSPickDemandItem.SerialNo,
                            wWMSPickDemandItem.ProductTime);
                    WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 配送后，维护配送条目的日计划
     *
     * @param wLoginUser 登录信息
     * @param wItem      配送单
     */
    private void WMS_Sorting_MaintainTaskStep(BMSEmployee wLoginUser, WMSPickDemand wItem) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSPickDemandItem> wList = WMSPickDemandItemDAO.getInstance().SelectList(wLoginUser, -1, wItem.ID, -1,
                    "", -1, wErrorCode);
            for (WMSPickDemandItem wWMSPickDemandItem : wList) {
                // 查询工序计划ID
                List<APSTaskStep> wTaskStepList = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wItem.OrderID,
                        -1, -1, -1, -1, wItem.PartID, wWMSPickDemandItem.PartPointID, -1, 1, null, null, null, null,
                        wErrorCode);
                if (wTaskStepList != null && wTaskStepList.size() > 0) {
                    wWMSPickDemandItem.TaskStepID = wTaskStepList.get(0).ID;
                }
                wWMSPickDemandItem.Status = WMSPickDemandItemStatus.Online.getValue();
                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 关闭消息
     *
     * @param wLoginUser 登录信息
     * @param wItem      配送单
     */
    private void WMS_Sorting_CloseMessage(BMSEmployee wLoginUser, WMSPickDemand wItem) {
        try {
            CoreServiceImpl.getInstance().BFC_MsgHandleTask(wLoginUser, BPMEventModule.MaterialSend.getValue(), 0, 3,
                    new ArrayList<>(Collections.singletonList(wItem.ID)), wLoginUser.ID, 1);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 发送待办消息
     */
    private void WMS_Sorting_SendMessage(BMSEmployee wLoginUser, WMSPickDemand wItem) {
        try {
            List<BFCMessage> wBFCMessageList = new ArrayList<>();
            BFCMessage wMessage = null;
            SimpleDateFormat wSDF = new SimpleDateFormat("yyyyMMdd");
            int wShiftID = Integer.parseInt(wSDF.format(Calendar.getInstance().getTime()));

            List<Integer> wUserIDList = new ArrayList<>();
            String wMessageText = "";
            String wNewMessage = "";
            // 交接
            if (wItem.Status == WMSPickDemandStatus.Picked.getValue()) {
                // 此处查询配送班成员
                wUserIDList = APSUtils.getInstance().QueryDeliveryClerk(wLoginUser, -1, wItem.PartID, -1).stream()
                        .map(p -> p.ID).distinct().collect(Collectors.toList());

                wMessageText = StringUtils.Format("【{0}】-【{2}】-【{3}】 {1}已分拣，待配送班交接",
                        BPMEventModule.MaterialSend.getLable(), wLoginUser.Name, wItem.PartNo, wItem.PartName);
            } else if (wItem.Status == WMSPickDemandStatus.Checked.getValue()) {// 配送
                wMessageText = StringUtils.Format("【{0}】-【{2}】-【{3}】 {1}已和库房交接，待班组接收物料",
                        BPMEventModule.MaterialSend.getLable(), wLoginUser.Name, wItem.PartNo, wItem.PartName);
                wNewMessage = StringUtils.Format("【{0}】-【{2}】-【{3}】 {1}已和库房交接，请及时配送物料到现场。",
                        BPMEventModule.MaterialSend.getLable(), wLoginUser.Name, wItem.PartNo, wItem.PartName);

                // 工位班组
                List<FMCWorkCharge> wWorkChargeList = APSConstans.GetFMCWorkChargeList().stream()
                        .filter(p -> p.Active == 1 && p.StationID == wItem.PartID).collect(Collectors.toList());
                for (FMCWorkCharge fmcWorkCharge : wWorkChargeList) {
                    // 班组成员
                    List<BMSEmployee> wUList = APSConstans.GetBMSEmployeeList().values().stream()
                            .filter(p -> p.DepartmentID == fmcWorkCharge.ClassID && p.Active == 1)
                            .collect(Collectors.toList());
                    if (wUList.size() > 0) {
                        wUserIDList.addAll(wUList.stream().map(p -> p.ID).distinct().collect(Collectors.toList()));
                    }
                }
            }

            for (int wUserID : wUserIDList) {
                // 发送任务消息到人员
                wMessage = new BFCMessage();
                wMessage.Active = 0;
                wMessage.CompanyID = 0;
                wMessage.CreateTime = Calendar.getInstance();
                wMessage.EditTime = Calendar.getInstance();
                wMessage.ID = 0;
                wMessage.MessageID = wItem.ID;
                wMessage.Title = wItem.DemandNo;
                wMessage.MessageText = wMessageText;
                wMessage.ModuleID = BPMEventModule.MaterialSend.getValue();
                wMessage.ResponsorID = wUserID;
                wMessage.ShiftID = wShiftID;
                wMessage.StationID = 0;
                wMessage.Type = BFCMessageType.Task.getValue();
                wBFCMessageList.add(wMessage);
            }
            if (StringUtils.isNotEmpty(wNewMessage)) {
                wMessage = new BFCMessage();
                wMessage.Active = 0;
                wMessage.CompanyID = 0;
                wMessage.CreateTime = Calendar.getInstance();
                wMessage.EditTime = Calendar.getInstance();
                wMessage.ID = 0;
                wMessage.MessageID = wItem.ID;
                wMessage.Title = wItem.DemandNo;
                wMessage.MessageText = wMessageText;
                wMessage.ModuleID = BPMEventModule.MaterialSend.getValue();
                wMessage.ResponsorID = wLoginUser.ID;
                wMessage.ShiftID = wShiftID;
                wMessage.StationID = 0;
                wMessage.Type = BFCMessageType.Task.getValue();
                wBFCMessageList.add(wMessage);
            }
            CoreServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    @Override
    public ServiceResult<String> WMS_ShowQRCode(BMSEmployee wLoginUser, int wDemandID, int wIsWaveNumber) {
        ServiceResult<String> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wItem = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);

            if (wIsWaveNumber == 1 && StringUtils.isEmpty(wItem.WaveNumber)) {
                wResult.FaultCode += "提示：该配送单波次号缺失!";
                return wResult;
            }

            SimpleDateFormat wSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String wCurrentTime = wSDF.format(Calendar.getInstance().getTime());
            // ①存放在二维码中的内容
            String text = "";
            if (wItem.Status == WMSPickDemandStatus.Picked.getValue()
                    || wItem.Status == WMSPickDemandStatus.Sended.getValue()) {
                text = StringUtils.Format("{0},{1},{2}", wItem.DemandNo, wLoginUser.LoginID, wCurrentTime);
                if (wIsWaveNumber == 1) {
                    text = StringUtils.Format("{0},{1},{2}", wItem.WaveNumber, wLoginUser.LoginID, wCurrentTime);
                }

                wItem.DeliveryID = wLoginUser.ID;
                WMSPickDemandDAO.getInstance().Update(wLoginUser, wItem, wErrorCode);

            } else if (wItem.Status == WMSPickDemandStatus.Checked.getValue()) {
                text = StringUtils.Format("{0},{1},{2},{3}", wItem.DemandNo, wItem.PartCode, wLoginUser.LoginID,
                        wCurrentTime);
            } else {
                wResult.FaultCode += "提示：状态错误!";
                return wResult;
            }

            // ②嵌入二维码的图片路径
            String imgPath = "";
            // ③文件名称
            String wFileName = UUID.randomUUID().toString().replaceAll("-", "");
            // ④生成的二维码的路径及名称
            String wDirePath = StringUtils.Format("{0}static/export/{1}.jpg",
                    Constants.getConfigPath().replace("config/", ""), wFileName);
            File wDirFile = new File(wDirePath);
            if (!wDirFile.exists()) {
                wDirFile.mkdirs();
            }
            // ⑥生成二维码
            QRCodeUtil.encode(text, imgPath, wDirePath, true);
            // ⑦返回路径
            wResult.Result = StringUtils.Format("/{0}/export/{1}.jpg",
                    Configuration.readConfigString("project.name", "application"), wFileName);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSPickDemandItem>> WMS_QueryOnlineMaterial(BMSEmployee wLoginUser, int wProductID,
                                                                          int wLineID, int wCustomerID, int wOrderID,
                                                                          int wPartID, int wStepID, String wMaterial,
                                                                          int wStatus,
                                                                          int wMaterialType) {
        ServiceResult<List<WMSPickDemandItem>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSPickDemandItemDAO.getInstance().WMS_QueryOnlineMaterial(wLoginUser, wProductID, wLineID,
                    wCustomerID, wOrderID, wPartID, wStepID, wMaterial, wStatus, wMaterialType, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_TechChange(BMSEmployee wLoginUser, TCMTechChangeNotice wTCMTechChangeNotice,
                                                 List<TCMMaterialChangeItems> wItemList) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wTCMTechChangeNotice.OrderList == null || wTCMTechChangeNotice.OrderList.size() <= 0) {
                wResult.FaultCode += "提示：无可处理车辆!";
                logger.info(wResult.FaultCode);
                return wResult;
            }

            List<Integer> wTypeList = new ArrayList<>(Arrays.asList(TCMChangeType.MaterialInsert.getValue(),
                    TCMChangeType.MaterialDelete.getValue(), TCMChangeType.MaterialNumberChange.getValue(),
                    TCMChangeType.MaterialPropertyChange.getValue()));
            wItemList = wItemList.stream().filter(p -> wTypeList.stream().anyMatch(q -> q == p.ChangeType))
                    .collect(Collectors.toList());
            if (wItemList.size() <= 0) {
                wResult.FaultCode += "提示：无可处理的物料变更!";
                logger.info(wResult.FaultCode);
                return wResult;
            }

            // ①按照车辆，遍历处理配送单
            for (int wOrderID : wTCMTechChangeNotice.OrderList) {
                // 订单工艺变更；新版变更逻辑；
                OrderTechChange_V1(wLoginUser, wOrderID, wTCMTechChangeNotice, wItemList);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 工艺变更处理逻辑
     */
    private void OrderTechChange_V1(BMSEmployee wLoginUser, int wOrderID, TCMTechChangeNotice wTCMTechChangeNotice,
                                    List<TCMMaterialChangeItems> wItemList) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            // 订单查询
            OMSOrder wOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wOrderID, wErrorCode);

            // 处理工位
            for (TCMMaterialChangeItems wTCMMaterialChangeItems : wItemList) {
                // 修改工位
                int wNewPartID = TCMMaterialChangeItemsDAO.getInstance().SelectPartID(wLoginUser, wOrder.RouteID,
                        wTCMMaterialChangeItems.PartPointID, wErrorCode);
                if (wNewPartID > 0) {
                    wTCMMaterialChangeItems.PlaceID = wNewPartID;
                    // wPartID = wNewPartID;
                }
            }

            // 按照工位分组进行处理
            List<Integer> wPartIDList = wItemList.stream().map(p -> p.PlaceID).distinct().collect(Collectors.toList());
            for (int wPartID : wPartIDList) {
                List<TCMMaterialChangeItems> wPartItemList = wItemList.stream().filter(p -> p.PlaceID == wPartID)
                        .collect(Collectors.toList());
                // 处理逻辑（必换）
                HandleLogic(wLoginUser, wOrder, wPartItemList, wPartID, wTCMTechChangeNotice);
                // 处理逻辑（委外）
                HandleLogic_Out(wLoginUser, wOrder, wPartItemList, wPartID, wTCMTechChangeNotice);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更处理逻辑（委外）
     */
    private void HandleLogic_Out(BMSEmployee wLoginUser, OMSOrder wOrder, List<TCMMaterialChangeItems> wItemList,
                                 int wPartID, TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            // 获取配置，判断是否需要处理委外的变更
            boolean wOutsourcingPlan = Configuration.readConfigString("OutsourcingPlan", "config/config")
                    .equals("1");
            if (!wOutsourcingPlan) {
                return;
            }

            List<TCMMaterialChangeItems> wAddedList = new ArrayList<>();
            List<TCMMaterialChangeItems> wDeletedList = new ArrayList<>();
            List<TCMMaterialChangeItems> wNumberChangeList = new ArrayList<>();
            // 遍历工艺变更明细，依次处理
            for (TCMMaterialChangeItems tcmMaterialChangeItems : wItemList) {
                switch (TCMChangeType.getEnumType(tcmMaterialChangeItems.ChangeType)) {
                    case MaterialInsert:// 物料新增
                        if (tcmMaterialChangeItems.OutsourceType == APSOutSourceType.WWBX.getValue()) {
                            wAddedList.add(tcmMaterialChangeItems);
                        }
                        break;
                    case MaterialDelete:// 物料删除
                        if (tcmMaterialChangeItems.OutsourceType == APSOutSourceType.WWBX.getValue()) {
                            wDeletedList.add(tcmMaterialChangeItems);
                        }
                        break;
                    case MaterialNumberChange:// 物料数量变更
                        if (tcmMaterialChangeItems.OutsourceType == APSOutSourceType.WWBX.getValue()) {
                            wNumberChangeList.add(tcmMaterialChangeItems);
                        }
                        break;
                    case MaterialPropertyChange:// 物料属性变更
                        // ①委外必修变其他，删除
                        if (tcmMaterialChangeItems.OldOutSourceType == APSOutSourceType.WWBX.getValue()
                                && tcmMaterialChangeItems.OutsourceType != APSOutSourceType.WWBX.getValue()) {
                            wDeletedList.add(tcmMaterialChangeItems);
                        }
                        // ②其他变委外必修，新增
                        if (tcmMaterialChangeItems.OldOutSourceType != APSOutSourceType.WWBX.getValue()
                                && tcmMaterialChangeItems.OutsourceType == APSOutSourceType.WWBX.getValue()) {
                            wAddedList.add(tcmMaterialChangeItems);
                        }
                        break;
                    default:
                        break;
                }
            }
            // 新增处理
            TechChangeAddHandle_Out(wLoginUser, wOrder, wAddedList, wPartID, wTCMTechChangeNotice);
            // 删除处理
            TechChangeDeleteHandle_Out(wLoginUser, wOrder, wDeletedList, wPartID, wTCMTechChangeNotice);
            // 数量新增
            List<TCMMaterialChangeItems> wNumberAddList = wNumberChangeList.stream()
                    .filter(p -> p.MaterialNumber > p.OldMaterialNumber).collect(Collectors.toList());
            TechChangeNumberAddHandle_Out(wLoginUser, wOrder, wNumberAddList, wPartID, wTCMTechChangeNotice);
            // 数量减少
            List<TCMMaterialChangeItems> wNumberRemoveList = wNumberChangeList.stream()
                    .filter(p -> p.MaterialNumber < p.OldMaterialNumber).collect(Collectors.toList());
            TechChangeNumberRemoveHandle_Out(wLoginUser, wOrder, wNumberRemoveList, wPartID, wTCMTechChangeNotice);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更处理逻辑
     */
    private void HandleLogic(BMSEmployee wLoginUser, OMSOrder wOrder, List<TCMMaterialChangeItems> wItemList,
                             int wPartID, TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            List<TCMMaterialChangeItems> wAddedList = new ArrayList<>();
            List<TCMMaterialChangeItems> wDeletedList = new ArrayList<>();
            List<TCMMaterialChangeItems> wNumberChangeList = new ArrayList<>();
            // 遍历工艺变更明细，依次处理
            for (TCMMaterialChangeItems tcmMaterialChangeItems : wItemList) {
                switch (TCMChangeType.getEnumType(tcmMaterialChangeItems.ChangeType)) {
                    case MaterialInsert:// 物料新增
                        if (tcmMaterialChangeItems.ReplaceType == APSReplaceType.MustChange.getValue()) {
                            wAddedList.add(tcmMaterialChangeItems);
                        }
                        break;
                    case MaterialDelete:// 物料删除
                        if (tcmMaterialChangeItems.ReplaceType == APSReplaceType.MustChange.getValue()) {
                            wDeletedList.add(tcmMaterialChangeItems);
                        }
                        break;
                    case MaterialNumberChange:// 物料数量变更
                        if (tcmMaterialChangeItems.ReplaceType == APSReplaceType.MustChange.getValue()) {
                            wNumberChangeList.add(tcmMaterialChangeItems);
                        }
                        break;
                    case MaterialPropertyChange:// 物料属性变更
                        // ①必换变偶换
                        if (tcmMaterialChangeItems.OldReplaceType == APSReplaceType.MustChange.getValue()
                                && tcmMaterialChangeItems.ReplaceType == APSReplaceType.OuChange.getValue()) {
                            wDeletedList.add(tcmMaterialChangeItems);
                        }
                        // ②偶换变必换
                        else if (tcmMaterialChangeItems.OldReplaceType == APSReplaceType.OuChange.getValue()
                                && tcmMaterialChangeItems.ReplaceType == APSReplaceType.MustChange.getValue()) {
                            wAddedList.add(tcmMaterialChangeItems);
                        }
                        // ③必换变委外
                        else if (tcmMaterialChangeItems.OldReplaceType == APSReplaceType.MustChange.getValue()
                                && tcmMaterialChangeItems.OldOutSourceType == APSOutSourceType.Default.getValue()
                                && tcmMaterialChangeItems.OutsourceType == APSOutSourceType.WWBX.getValue()) {
                            wDeletedList.add(tcmMaterialChangeItems);
                        }
                        // ④委外变必换
                        else if (tcmMaterialChangeItems.OldReplaceType == APSReplaceType.Default.getValue()
                                && (tcmMaterialChangeItems.OldOutSourceType == APSOutSourceType.WWBX.getValue()
                                || tcmMaterialChangeItems.OldOutSourceType == APSOutSourceType.WWOX.getValue())
                                && tcmMaterialChangeItems.ReplaceType == APSReplaceType.MustChange.getValue()) {
                            wAddedList.add(tcmMaterialChangeItems);
                        }
                        // ⑤非客供变客供
                        else if (tcmMaterialChangeItems.OldCustomerMaterial == 0 && tcmMaterialChangeItems.CustomerMaterial == 1) {
                            wAddedList.add(tcmMaterialChangeItems);
                        }
                        // ⑥自修变必换
                        else if (tcmMaterialChangeItems.OldReplaceType == APSReplaceType.Default.getValue() && (tcmMaterialChangeItems.OldOutSourceType == APSOutSourceType.ZXBX.getValue() || tcmMaterialChangeItems.OldOutSourceType == APSOutSourceType.ZXOX.getValue()) && tcmMaterialChangeItems.ReplaceType == APSReplaceType.MustChange.getValue()) {
                            wAddedList.add(tcmMaterialChangeItems);
                        }
                        break;
                    default:
                        break;
                }
            }
            // 新增处理
            TechChangeAddHandle(wLoginUser, wOrder, wAddedList, wPartID, wTCMTechChangeNotice);
            // 删除处理
            TechChangeDeleteHandle(wLoginUser, wOrder, wDeletedList, wPartID, wTCMTechChangeNotice);
            // 数量新增
            List<TCMMaterialChangeItems> wNumberAddList = wNumberChangeList.stream()
                    .filter(p -> p.MaterialNumber > p.OldMaterialNumber).collect(Collectors.toList());
            TechChangeNumberAddHandle(wLoginUser, wOrder, wNumberAddList, wPartID, wTCMTechChangeNotice);
            // 数量减少
            List<TCMMaterialChangeItems> wNumberRemoveList = wNumberChangeList.stream()
                    .filter(p -> p.MaterialNumber < p.OldMaterialNumber).collect(Collectors.toList());
            TechChangeNumberRemoveHandle(wLoginUser, wOrder, wNumberRemoveList, wPartID, wTCMTechChangeNotice);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更逻辑数量减少处理
     */
    private void TechChangeNumberRemoveHandle(BMSEmployee wLoginUser, OMSOrder wOrder,
                                              List<TCMMaterialChangeItems> wNumberRemoveList, int wPartID,
                                              TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            if (wNumberRemoveList == null || wNumberRemoveList.size() <= 0) {
                return;
            }

            // 克隆数据，防止数据错乱
            List<TCMMaterialChangeItems> wNumberRemoveCloneList = CloneTool.CloneArray(wNumberRemoveList,
                    TCMMaterialChangeItems.class);

            List<TCMMaterialChangeItems> wToBackList = new ArrayList<>();

            // 获取工序列表
            List<Integer> wPartPointIDList = wNumberRemoveCloneList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            for (int wPartPointID : wPartPointIDList) {
                List<APSTaskStep> apsTaskSteps = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                        -1, -1, -1, -1, wPartID, wPartPointID, -1, 1, null, null, null, null, wErrorCode);
                if (apsTaskSteps.size() <= 0) {
                    continue;
                }

                List<TCMMaterialChangeItems> wPartPointItems = wNumberRemoveCloneList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                for (TCMMaterialChangeItems wTCMMaterialChangeItems : wPartPointItems) {
                    // 查询配送单明细
                    WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance()
                            .SelectBySourceTypeAndMaterialID(wLoginUser, wOrder.ID,
                                    wPartID,
                                    wPartPointID,
                                    WMSPickDemandSourceType.Plan.getValue(), wTCMMaterialChangeItems.MaterialID,
                                    wErrorCode);
                    if (wWMSPickDemandItem.ID <= 0) {
                        continue;
                    }

                    wTCMMaterialChangeItems.DemandItemID = wWMSPickDemandItem.ID;

                    switch (WMSPickDemandStatusNew.getEnumType(wWMSPickDemandItem.ParentStatus)) {
                        case Saved:
                        case Canceld:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Saved) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = wTCMMaterialChangeItems.MaterialNumber;
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                            }
                            break;
                        case NotStart:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Sended) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = wTCMMaterialChangeItems.MaterialNumber;
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                                WMSServiceImpl.getInstance().WMS_TestUpdatePickDemand(wLoginUser,
                                        wmsPickDemandItem.DemandID,
                                        String.valueOf(wmsPickDemandItem.ID));
                            }
                            break;
                        case Running:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Picking:
                                case Picked:
                                case Finished:
                                case Canceled: {
                                    WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                            wLoginUser,
                                            wWMSPickDemandItem.ID,
                                            wErrorCode);
                                    wmsPickDemandItem.FQTY = wTCMMaterialChangeItems.MaterialNumber;
                                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                            wErrorCode);
                                    WMSServiceImpl.getInstance().WMS_TestUpdatePickDemand(wLoginUser,
                                            wmsPickDemandItem.DemandID,
                                            String.valueOf(wmsPickDemandItem.ID));
                                }
                                break;
                                default:
                                    break;
                            }
                            break;
                        case Finished:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Finished
                                    && wWMSPickDemandItem.PickedNumber > 0) {
                                wTCMMaterialChangeItems.MaterialNumber = wTCMMaterialChangeItems.OldMaterialNumber
                                        - wTCMMaterialChangeItems.MaterialNumber;
                                wToBackList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case FinishClosed:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Finished:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()
                                            && wWMSPickDemandItem.PickedNumber > 0) {
                                        wTCMMaterialChangeItems.MaterialNumber = wTCMMaterialChangeItems.OldMaterialNumber
                                                - wTCMMaterialChangeItems.MaterialNumber;
                                        wToBackList.add(wTCMMaterialChangeItems);
                                    }
                                    break;
                                case Canceled:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                                        WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance()
                                                .SelectByID(wLoginUser,
                                                        wWMSPickDemandItem.ID,
                                                        wErrorCode);
                                        wmsPickDemandItem.FQTY = wTCMMaterialChangeItems.MaterialNumber;
                                        WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                                wErrorCode);
                                    }
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }

            // 执行工艺变更退料逻辑
            if (wToBackList.size() > 0) {
                DoTechChangeReturn(wLoginUser, wTCMTechChangeNotice, wToBackList, wOrder, wPartID, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更逻辑数量减少处理
     */
    private void TechChangeNumberRemoveHandle_Out(BMSEmployee wLoginUser, OMSOrder wOrder,
                                                  List<TCMMaterialChangeItems> wNumberRemoveList, int wPartID,
                                                  TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            if (wNumberRemoveList == null || wNumberRemoveList.size() <= 0) {
                return;
            }

            // 克隆数据，防止数据错乱
            List<TCMMaterialChangeItems> wNumberRemoveCloneList = CloneTool.CloneArray(wNumberRemoveList,
                    TCMMaterialChangeItems.class);

            List<TCMMaterialChangeItems> wToBackList = new ArrayList<>();

            // 获取工序列表
            List<Integer> wPartPointIDList = wNumberRemoveCloneList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            for (int wPartPointID : wPartPointIDList) {
                List<APSTaskStep> apsTaskSteps = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                        -1, -1, -1, -1, wPartID, wPartPointID, -1, 1, null, null, null, null, wErrorCode);
                if (apsTaskSteps.size() <= 0) {
                    continue;
                }

                List<TCMMaterialChangeItems> wPartPointItems = wNumberRemoveCloneList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                for (TCMMaterialChangeItems wTCMMaterialChangeItems : wPartPointItems) {
                    // 查询配送单明细
                    WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance()
                            .SelectBySourceTypeAndMaterialID(wLoginUser, wOrder.ID,
                                    wPartID,
                                    wPartPointID,
                                    WMSPickDemandSourceType.Plan_Out.getValue(), wTCMMaterialChangeItems.MaterialID,
                                    wErrorCode);
                    if (wWMSPickDemandItem.ID <= 0) {
                        continue;
                    }

                    wTCMMaterialChangeItems.DemandItemID = wWMSPickDemandItem.ID;

                    switch (WMSPickDemandStatusNew.getEnumType(wWMSPickDemandItem.ParentStatus)) {
                        case Saved:
                        case Canceld:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Saved) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = wTCMMaterialChangeItems.MaterialNumber;
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                            }
                            break;
                        case NotStart:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Sended) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = wTCMMaterialChangeItems.MaterialNumber;
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                                WMSServiceImpl.getInstance().WMS_TestUpdatePickDemand(wLoginUser,
                                        wmsPickDemandItem.DemandID,
                                        String.valueOf(wmsPickDemandItem.ID));
                            }
                            break;
                        case Running:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Picking:
                                case Picked:
                                case Finished:
                                case Canceled: {
                                    WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                            wLoginUser,
                                            wWMSPickDemandItem.ID,
                                            wErrorCode);
                                    wmsPickDemandItem.FQTY = wTCMMaterialChangeItems.MaterialNumber;
                                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                            wErrorCode);
                                    WMSServiceImpl.getInstance().WMS_TestUpdatePickDemand(wLoginUser,
                                            wmsPickDemandItem.DemandID,
                                            String.valueOf(wmsPickDemandItem.ID));
                                }
                                break;
                                default:
                                    break;
                            }
                            break;
                        case Finished:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Finished
                                    && wWMSPickDemandItem.PickedNumber > 0) {
                                wTCMMaterialChangeItems.MaterialNumber = wTCMMaterialChangeItems.OldMaterialNumber
                                        - wTCMMaterialChangeItems.MaterialNumber;
                                wToBackList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case FinishClosed:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Finished:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()
                                            && wWMSPickDemandItem.PickedNumber > 0) {
                                        wTCMMaterialChangeItems.MaterialNumber = wTCMMaterialChangeItems.OldMaterialNumber
                                                - wTCMMaterialChangeItems.MaterialNumber;
                                        wToBackList.add(wTCMMaterialChangeItems);
                                    }
                                    break;
                                case Canceled:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                                        WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance()
                                                .SelectByID(wLoginUser,
                                                        wWMSPickDemandItem.ID,
                                                        wErrorCode);
                                        wmsPickDemandItem.FQTY = wTCMMaterialChangeItems.MaterialNumber;
                                        WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                                wErrorCode);
                                    }
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }

            // 执行工艺变更退料逻辑
            if (wToBackList.size() > 0) {
                DoTechChangeReturn(wLoginUser, wTCMTechChangeNotice, wToBackList, wOrder, wPartID, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更逻辑数量新增处理
     */
    private void TechChangeNumberAddHandle(BMSEmployee wLoginUser, OMSOrder wOrder,
                                           List<TCMMaterialChangeItems> wNumberAddList, int wPartID,
                                           TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            if (wNumberAddList == null || wNumberAddList.size() <= 0) {
                return;
            }

            // ①根据物料iD集合，查询反冲料集合
            List<Integer> wMaterialIDList = wNumberAddList.stream().map(p -> p.MaterialID).distinct()
                    .collect(Collectors.toList());
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            Map<Integer, Double> wMaterialPackMap = MRPMaterialPlanDAO.getInstance().GetMaterialPackMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            // 获取反冲物料列表
            boolean wIsSendRecoilMaterial = Configuration.readConfigString("IsSendRecoilMaterial", "config/config")
                    .equals("1");

            List<TCMMaterialChangeItems> wRealAddList = new ArrayList<>();

            // 获取工序列表
            List<Integer> wPartPointIDList = wNumberAddList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            for (int wPartPointID : wPartPointIDList) {
                List<APSTaskStep> apsTaskSteps = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                        -1, -1, -1, -1, wPartID, wPartPointID, -1, 1, null, null, null, null, wErrorCode);
                if (apsTaskSteps.size() <= 0) {
                    continue;
                }

                List<TCMMaterialChangeItems> wPartPointItems = wNumberAddList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                // 工序已完工，不做操作
                if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                    continue;
                }

                for (TCMMaterialChangeItems wTCMMaterialChangeItems : wPartPointItems) {
                    // 查询配送单明细
                    WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance()
                            .SelectBySourceTypeAndMaterialID(wLoginUser, wOrder.ID,
                                    wPartID,
                                    wPartPointID,
                                    WMSPickDemandSourceType.Plan.getValue(), wTCMMaterialChangeItems.MaterialID,
                                    wErrorCode);
                    if (wWMSPickDemandItem.ID <= 0) {
                        continue;
                    }

                    wTCMMaterialChangeItems.DemandItemID = wWMSPickDemandItem.ID;

                    switch (WMSPickDemandStatusNew.getEnumType(wWMSPickDemandItem.ParentStatus)) {
                        case Saved:
                        case Canceld:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Saved) {
                                wRealAddList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case NotStart:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Sended) {
                                wRealAddList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case Running:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Picking:
                                case Picked:
                                case Finished:
                                case Canceled: {
                                    wRealAddList.add(wTCMMaterialChangeItems);
                                }
                                break;
                                default:
                                    break;
                            }
                            break;
                        case Finished:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Finished) {
                                wRealAddList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case FinishClosed:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Finished:
                                case Canceled:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                                    }
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }

            // 创建新单
            if (wRealAddList.size() > 0) {
                // 克隆数据
                List<TCMMaterialChangeItems> wCloneList = CloneTool.CloneArray(wRealAddList,
                        TCMMaterialChangeItems.class);

                for (TCMMaterialChangeItems tcmMaterialChangeItems : wCloneList) {
                    tcmMaterialChangeItems.MaterialNumber = tcmMaterialChangeItems.MaterialNumber
                            - tcmMaterialChangeItems.OldMaterialNumber;
                }
                CreateNewPickDemand(wLoginUser, wCloneList, wTCMTechChangeNotice, wOrder, wPartID, wMaterialTypeMap,
                        wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更逻辑数量新增处理
     */
    private void TechChangeNumberAddHandle_Out(BMSEmployee wLoginUser, OMSOrder wOrder,
                                               List<TCMMaterialChangeItems> wNumberAddList, int wPartID,
                                               TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            if (wNumberAddList == null || wNumberAddList.size() <= 0) {
                return;
            }

            // ①根据物料iD集合，查询反冲料集合
            List<Integer> wMaterialIDList = wNumberAddList.stream().map(p -> p.MaterialID).distinct()
                    .collect(Collectors.toList());
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            Map<Integer, Double> wMaterialPackMap = MRPMaterialPlanDAO.getInstance().GetMaterialPackMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            // 获取反冲物料列表
            boolean wIsSendRecoilMaterial = Configuration.readConfigString("IsSendRecoilMaterial", "config/config")
                    .equals("1");

            List<TCMMaterialChangeItems> wRealAddList = new ArrayList<>();

            // 获取工序列表
            List<Integer> wPartPointIDList = wNumberAddList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            for (int wPartPointID : wPartPointIDList) {
                List<APSTaskStep> apsTaskSteps = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                        -1, -1, -1, -1, wPartID, wPartPointID, -1, 1, null, null, null, null, wErrorCode);
                if (apsTaskSteps.size() <= 0) {
                    continue;
                }

                List<TCMMaterialChangeItems> wPartPointItems = wNumberAddList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                // 工序已完工，不做操作
                if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                    continue;
                }

                for (TCMMaterialChangeItems wTCMMaterialChangeItems : wPartPointItems) {
                    // 查询配送单明细
                    WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance()
                            .SelectBySourceTypeAndMaterialID(wLoginUser, wOrder.ID,
                                    wPartID,
                                    wPartPointID,
                                    WMSPickDemandSourceType.Plan_Out.getValue(), wTCMMaterialChangeItems.MaterialID,
                                    wErrorCode);
                    if (wWMSPickDemandItem.ID <= 0) {
                        continue;
                    }

                    wTCMMaterialChangeItems.DemandItemID = wWMSPickDemandItem.ID;

                    switch (WMSPickDemandStatusNew.getEnumType(wWMSPickDemandItem.ParentStatus)) {
                        case Saved:
                        case Canceld:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Saved) {
                                wRealAddList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case NotStart:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Sended) {
                                wRealAddList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case Running:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Picking:
                                case Picked:
                                case Finished:
                                case Canceled: {
                                    wRealAddList.add(wTCMMaterialChangeItems);
                                }
                                break;
                                default:
                                    break;
                            }
                            break;
                        case Finished:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Finished) {
                                wRealAddList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case FinishClosed:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Finished:
                                case Canceled:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                                    }
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }

            // 创建新单
            if (wRealAddList.size() > 0) {
                // 克隆数据
                List<TCMMaterialChangeItems> wCloneList = CloneTool.CloneArray(wRealAddList,
                        TCMMaterialChangeItems.class);

                for (TCMMaterialChangeItems tcmMaterialChangeItems : wCloneList) {
                    tcmMaterialChangeItems.MaterialNumber = tcmMaterialChangeItems.MaterialNumber
                            - tcmMaterialChangeItems.OldMaterialNumber;
                }
                CreateNewPickDemand_Out(wLoginUser, wCloneList, wTCMTechChangeNotice, wOrder, wPartID, wMaterialTypeMap,
                        wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更逻辑删除处理
     */
    private void TechChangeDeleteHandle(BMSEmployee wLoginUser, OMSOrder wOrder,
                                        List<TCMMaterialChangeItems> wDeletedList, int wPartID,
                                        TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            if (wDeletedList == null || wDeletedList.size() <= 0) {
                return;
            }

            List<TCMMaterialChangeItems> wToBackList = new ArrayList<>();

            // 获取工序列表
            List<Integer> wPartPointIDList = wDeletedList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            for (int wPartPointID : wPartPointIDList) {
                List<APSTaskStep> apsTaskSteps = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                        -1, -1, -1, -1, wPartID, wPartPointID, -1, 1, null, null, null, null, wErrorCode);
                if (apsTaskSteps.size() <= 0) {
                    continue;
                }

                List<TCMMaterialChangeItems> wPartPointItems = wDeletedList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                for (TCMMaterialChangeItems wTCMMaterialChangeItems : wPartPointItems) {
                    // 查询配送单明细
                    WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance()
                            .SelectBySourceTypeAndMaterialID(wLoginUser, wOrder.ID,
                                    wPartID,
                                    wPartPointID,
                                    WMSPickDemandSourceType.Plan.getValue(), wTCMMaterialChangeItems.MaterialID,
                                    wErrorCode);
                    if (wWMSPickDemandItem.ID <= 0) {
                        continue;
                    }

                    wTCMMaterialChangeItems.DemandItemID = wWMSPickDemandItem.ID;

                    switch (WMSPickDemandStatusNew.getEnumType(wWMSPickDemandItem.ParentStatus)) {
                        case Saved:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Saved) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = 0;
                                wmsPickDemandItem.DeleteFlag = 1;
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                            }
                            break;
                        case NotStart:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Sended) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = 0;
                                wmsPickDemandItem.DeleteFlag = 1;
                                wmsPickDemandItem.Status = WMSPickDemandItemStatusNew.Canceled.getValue();
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                                WMSServiceImpl.getInstance().WMS_TestUpdatePickDemand(wLoginUser,
                                        wmsPickDemandItem.DemandID,
                                        String.valueOf(wmsPickDemandItem.ID));
                            }
                            break;
                        case Running:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Picking:
                                case Picked: {
                                    WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                            wLoginUser,
                                            wWMSPickDemandItem.ID,
                                            wErrorCode);
                                    wmsPickDemandItem.FQTY = 0;
                                    wmsPickDemandItem.DeleteFlag = 1;
                                    wmsPickDemandItem.Status = WMSPickDemandItemStatusNew.Canceled.getValue();
                                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                            wErrorCode);
                                    WMSServiceImpl.getInstance().WMS_TestUpdatePickDemand(wLoginUser,
                                            wmsPickDemandItem.DemandID,
                                            String.valueOf(wmsPickDemandItem.ID));
                                }
                                break;
                                case Finished:
                                    if (wWMSPickDemandItem.PickedNumber > 0) {
                                        wToBackList.add(wTCMMaterialChangeItems);
                                    }
                                    break;
                                case Canceled: {
                                    WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                            wLoginUser,
                                            wWMSPickDemandItem.ID,
                                            wErrorCode);
                                    wmsPickDemandItem.FQTY = 0;
                                    wmsPickDemandItem.DeleteFlag = 1;
                                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                            wErrorCode);
                                }
                                break;
                                default:
                                    break;
                            }
                            break;
                        case Finished:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Finished
                                    && wWMSPickDemandItem.PickedNumber > 0) {
                                wToBackList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case FinishClosed:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Finished:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()
                                            && wWMSPickDemandItem.PickedNumber > 0) {
                                        wToBackList.add(wTCMMaterialChangeItems);
                                    }
                                    break;
                                case Canceled:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                                        WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance()
                                                .SelectByID(wLoginUser,
                                                        wWMSPickDemandItem.ID,
                                                        wErrorCode);
                                        wmsPickDemandItem.FQTY = 0;
                                        wmsPickDemandItem.DeleteFlag = 1;
                                        WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                                wErrorCode);
                                    }
                                    break;
                                default:
                                    break;
                            }
                            break;
                        case Canceld:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Saved) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = 0;
                                wmsPickDemandItem.DeleteFlag = 1;
                                wmsPickDemandItem.Status = WMSPickDemandItemStatusNew.Canceled.getValue();
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                            }
                            break;
                        default:
                            break;
                    }
                }
            }

            // 执行工艺变更退料逻辑
            if (wToBackList.size() > 0) {
                DoTechChangeReturn(wLoginUser, wTCMTechChangeNotice, wToBackList, wOrder, wPartID, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更逻辑删除处理
     */
    private void TechChangeDeleteHandle_Out(BMSEmployee wLoginUser, OMSOrder wOrder,
                                            List<TCMMaterialChangeItems> wDeletedList, int wPartID,
                                            TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            if (wDeletedList == null || wDeletedList.size() <= 0) {
                return;
            }

            List<TCMMaterialChangeItems> wToBackList = new ArrayList<>();

            // 获取工序列表
            List<Integer> wPartPointIDList = wDeletedList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            for (int wPartPointID : wPartPointIDList) {
                List<APSTaskStep> apsTaskSteps = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                        -1, -1, -1, -1, wPartID, wPartPointID, -1, 1, null, null, null, null, wErrorCode);
                if (apsTaskSteps.size() <= 0) {
                    continue;
                }

                List<TCMMaterialChangeItems> wPartPointItems = wDeletedList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                for (TCMMaterialChangeItems wTCMMaterialChangeItems : wPartPointItems) {
                    // 查询配送单明细
                    WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance()
                            .SelectBySourceTypeAndMaterialID(wLoginUser, wOrder.ID,
                                    wPartID,
                                    wPartPointID,
                                    WMSPickDemandSourceType.Plan_Out.getValue(), wTCMMaterialChangeItems.MaterialID,
                                    wErrorCode);
                    if (wWMSPickDemandItem.ID <= 0) {
                        continue;
                    }

                    wTCMMaterialChangeItems.DemandItemID = wWMSPickDemandItem.ID;

                    switch (WMSPickDemandStatusNew.getEnumType(wWMSPickDemandItem.ParentStatus)) {
                        case Saved:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Saved) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = 0;
                                wmsPickDemandItem.DeleteFlag = 1;
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                            }
                            break;
                        case NotStart:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Sended) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = 0;
                                wmsPickDemandItem.DeleteFlag = 1;
                                wmsPickDemandItem.Status = WMSPickDemandItemStatusNew.Canceled.getValue();
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                                WMSServiceImpl.getInstance().WMS_TestUpdatePickDemand(wLoginUser,
                                        wmsPickDemandItem.DemandID,
                                        String.valueOf(wmsPickDemandItem.ID));
                            }
                            break;
                        case Running:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Picking:
                                case Picked: {
                                    WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                            wLoginUser,
                                            wWMSPickDemandItem.ID,
                                            wErrorCode);
                                    wmsPickDemandItem.FQTY = 0;
                                    wmsPickDemandItem.DeleteFlag = 1;
                                    wmsPickDemandItem.Status = WMSPickDemandItemStatusNew.Canceled.getValue();
                                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                            wErrorCode);
                                    WMSServiceImpl.getInstance().WMS_TestUpdatePickDemand(wLoginUser,
                                            wmsPickDemandItem.DemandID,
                                            String.valueOf(wmsPickDemandItem.ID));
                                }
                                break;
                                case Finished:
                                    if (wWMSPickDemandItem.PickedNumber > 0) {
                                        wToBackList.add(wTCMMaterialChangeItems);
                                    }
                                    break;
                                case Canceled: {
                                    WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                            wLoginUser,
                                            wWMSPickDemandItem.ID,
                                            wErrorCode);
                                    wmsPickDemandItem.FQTY = 0;
                                    wmsPickDemandItem.DeleteFlag = 1;
                                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                            wErrorCode);
                                }
                                break;
                                default:
                                    break;
                            }
                            break;
                        case Finished:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Finished
                                    && wWMSPickDemandItem.PickedNumber > 0) {
                                wToBackList.add(wTCMMaterialChangeItems);
                            }
                            break;
                        case FinishClosed:
                            switch (WMSPickDemandItemStatusNew.getEnumType(wWMSPickDemandItem.Status)) {
                                case Finished:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()
                                            && wWMSPickDemandItem.PickedNumber > 0) {
                                        wToBackList.add(wTCMMaterialChangeItems);
                                    }
                                    break;
                                case Canceled:
                                    if (apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                                        WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance()
                                                .SelectByID(wLoginUser,
                                                        wWMSPickDemandItem.ID,
                                                        wErrorCode);
                                        wmsPickDemandItem.FQTY = 0;
                                        wmsPickDemandItem.DeleteFlag = 1;
                                        WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                                wErrorCode);
                                    }
                                    break;
                                default:
                                    break;
                            }
                            break;
                        case Canceld:
                            if (WMSPickDemandItemStatusNew
                                    .getEnumType(wWMSPickDemandItem.Status) == WMSPickDemandItemStatusNew.Saved) {
                                WMSPickDemandItem wmsPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(
                                        wLoginUser,
                                        wWMSPickDemandItem.ID,
                                        wErrorCode);
                                wmsPickDemandItem.FQTY = 0;
                                wmsPickDemandItem.DeleteFlag = 1;
                                wmsPickDemandItem.Status = WMSPickDemandItemStatusNew.Canceled.getValue();
                                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem,
                                        wErrorCode);
                            }
                            break;
                        default:
                            break;
                    }
                }
            }

            // 执行工艺变更退料逻辑
            if (wToBackList.size() > 0) {
                DoTechChangeReturn(wLoginUser, wTCMTechChangeNotice, wToBackList, wOrder, wPartID, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 获取班组长
     */
    private List<Integer> GetMonitorByPart(BMSEmployee wLoginUser, int wPartID, OutResult<Integer> wErrorCode) {
        List<Integer> wResult = new ArrayList<>();
        try {
            List<FMCWorkCharge> wChargeList = APSConstans.GetFMCWorkChargeList().stream()
                    .filter(p -> p.StationID == wPartID && p.Active == 1).collect(Collectors.toList());
            List<BMSEmployee> wUserList = APSConstans.GetBMSEmployeeList().values().stream()
                    .filter(p -> wChargeList.stream().anyMatch(q -> q.ClassID == p.DepartmentID)
                            && APSConstans.GetBMSPosition(p.Position).DutyID == 1 && p.Active == 1)
                    .collect(Collectors.toList());
            wResult = wUserList.stream().map(p -> p.ID).distinct().collect(Collectors.toList());
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 执行工艺变更退料逻辑
     */
    private void DoTechChangeReturn(BMSEmployee wLoginUser, TCMTechChangeNotice wTCMTechChangeNotice,
                                    List<TCMMaterialChangeItems> wToBackList, OMSOrder wOrder, int wPartID,
                                    OutResult<Integer> wErrorCode) {
        try {
            if (wToBackList == null || wToBackList.size() <= 0) {
                return;
            }
            // ①提取工序
            List<Integer> wPartPointIDList = wToBackList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            // ②按照订单、工序分开推送退料待办任务
            for (int wPartPointID : wPartPointIDList) {
                List<TCMMaterialChangeItems> wMESMaterialReturnItemList = wToBackList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                // 查找工序作业人员
                List<Integer> wUserList = GetUserListByOrderIDAndPartPointID(wLoginUser, wOrder.ID,
                        wPartPointID);
                // 若工位作业任务没有，则给到工位班组长
                if (wUserList.size() <= 0) {
                    wUserList = GetMonitorByPart(wLoginUser, wPartID, wErrorCode);
                }

                if (wUserList.size() <= 0) {
                    continue;
                }
                // 发送待办消息
                List<BFCMessage> wBFCMessageList = new ArrayList<>();
                BFCMessage wMessage = null;
                int wShiftID = MESServer.MES_QueryShiftID(wLoginUser.CompanyID, Calendar.getInstance(),
                        APSShiftPeriod.Day, FMCShiftLevel.Day, 0);
                for (int wUserID : wUserList) {
                    // 发送任务消息到人员
                    wMessage = new BFCMessage();
                    wMessage.Active = 0;
                    wMessage.CompanyID = 0;
                    wMessage.CreateTime = Calendar.getInstance();
                    wMessage.EditTime = Calendar.getInstance();
                    wMessage.ID = 0;
                    wMessage.MessageID = wTCMTechChangeNotice.ID;
                    wMessage.Title = wTCMTechChangeNotice.Code;
                    // 【工艺变更退料】 安旭梅已通过工艺变更审批，请及时完成退料。
                    wMessage.MessageText = StringUtils.Format("【{0}】-【{2}-{3}】 {1}已通过工艺变更审批，请及时完成退料。",
                            BPMEventModule.TechReturnMaterial.getLable(), wLoginUser.Name, wOrder.PartNo,
                            APSConstans.GetFPCPartPointName(wPartPointID));
                    wMessage.ModuleID = BPMEventModule.TechReturnMaterial.getValue();
                    wMessage.ResponsorID = wUserID;
                    wMessage.ShiftID = wShiftID;
                    wMessage.StationID = wOrder.ID;
                    wMessage.StepID = wPartPointID;
                    wMessage.Type = BFCMessageType.Task.getValue();
                    wBFCMessageList.add(wMessage);
                }
                CoreServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
                // 保存工艺变更退料信息
                for (TCMMaterialChangeItems wMESMaterialReturnItem : wMESMaterialReturnItemList) {
                    WMSTechMaterialReturn wWMSTechMaterialReturn = new WMSTechMaterialReturn(0, wTCMTechChangeNotice.ID,
                            wMESMaterialReturnItem.DemandItemID, wMESMaterialReturnItem.MaterialNumber,
                            wOrder.ID, wMESMaterialReturnItem.PartPointID);
                    QMSServiceImpl.getInstance().WMS_WMS_UpdateWMSTechMaterialReturn(wLoginUser,
                            wWMSTechMaterialReturn);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更逻辑新增处理
     */
    private void TechChangeAddHandle(BMSEmployee wLoginUser, OMSOrder wOrder, List<TCMMaterialChangeItems> wAddedList,
                                     int wPartID, TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            if (wAddedList == null || wAddedList.size() <= 0) {
                return;
            }

            // ①根据物料iD集合，查询反冲料集合
            List<Integer> wMaterialIDList = wAddedList.stream().map(p -> p.MaterialID).distinct()
                    .collect(Collectors.toList());
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            Map<Integer, Double> wMaterialPackMap = MRPMaterialPlanDAO.getInstance().GetMaterialPackMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            // 获取反冲物料列表
            boolean wIsSendRecoilMaterial = Configuration.readConfigString("IsSendRecoilMaterial", "config/config")
                    .equals("1");

            List<TCMMaterialChangeItems> wRealAddList = new ArrayList<>();

            // 获取工序列表
            List<Integer> wPartPointIDList = wAddedList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            // 根据订单、工位、工序获取工序任务
            for (int wPartPointID : wPartPointIDList) {
                List<APSTaskStep> apsTaskSteps = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                        -1, -1, -1, -1, wPartID, wPartPointID, -1, 1, null, null, null, null, wErrorCode);

                // 查询配送单
                WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectBySourceType(wLoginUser,
                        wOrder.ID, wPartID,
                        wPartPointID,
                        WMSPickDemandSourceType.Plan.getValue(), wErrorCode);
                if (wWMSPickDemandItem.ID <= 0) {
                    if (apsTaskSteps.size() > 0 && apsTaskSteps.get(0).Status != APSTaskStatus.Done.getValue()) {
                        wRealAddList.addAll(wAddedList.stream().filter(p -> p.PartPointID == wPartPointID)
                                .collect(Collectors.toList()));
                    } else if (apsTaskSteps.size() <= 0) {
                        wRealAddList.addAll(wAddedList.stream().filter(p -> p.PartPointID == wPartPointID)
                                .collect(Collectors.toList()));
                    }
                    continue;
                }
                // 工序完工不做处理
                if (apsTaskSteps.size() > 0 && apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                    continue;
                }

                List<TCMMaterialChangeItems> wPartPointItems = wAddedList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                switch (WMSPickDemandStatusNew.getEnumType(wWMSPickDemandItem.ParentStatus)) {
                    case Saved:// 保存状态→原单增加明细行
                        AddDetailRow(wLoginUser, wWMSPickDemandItem, wPartPointItems, wOrder, wMaterialTypeMap,
                                wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
                        break;
                    case NotStart:// 未开始→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                    case Running:// 进行中→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                    case Finished:// 已完成→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                    case FinishClosed:// 完工关闭→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                    case Canceld:// 已取消→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                        wRealAddList.addAll(wPartPointItems);
                        break;
                    default:
                        break;
                }
            }

            // 创建新的配送单和明细
            if (wRealAddList.size() <= 0) {
                return;
            }

            // 创建新的物料配送单
            CreateNewPickDemand(wLoginUser, wRealAddList, wTCMTechChangeNotice, wOrder, wPartID, wMaterialTypeMap,
                    wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 工艺变更逻辑新增处理（委外）
     */
    private void TechChangeAddHandle_Out(BMSEmployee wLoginUser, OMSOrder wOrder,
                                         List<TCMMaterialChangeItems> wAddedList,
                                         int wPartID, TCMTechChangeNotice wTCMTechChangeNotice) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            if (wAddedList == null || wAddedList.size() <= 0) {
                return;
            }

            // ①根据物料iD集合，查询反冲料集合
            List<Integer> wMaterialIDList = wAddedList.stream().map(p -> p.MaterialID).distinct()
                    .collect(Collectors.toList());
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            Map<Integer, Double> wMaterialPackMap = MRPMaterialPlanDAO.getInstance().GetMaterialPackMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            // 获取反冲物料列表
            boolean wIsSendRecoilMaterial = Configuration.readConfigString("IsSendRecoilMaterial", "config/config")
                    .equals("1");

            List<TCMMaterialChangeItems> wRealAddList = new ArrayList<>();

            // 获取工序列表
            List<Integer> wPartPointIDList = wAddedList.stream().map(p -> p.PartPointID).distinct()
                    .collect(Collectors.toList());
            // 根据订单、工位、工序获取工序任务
            for (int wPartPointID : wPartPointIDList) {
                List<APSTaskStep> apsTaskSteps = APSTaskStepDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID,
                        -1, -1, -1, -1, wPartID, wPartPointID, -1, 1, null, null, null, null, wErrorCode);

                // 查询配送单
                WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectBySourceType(wLoginUser,
                        wOrder.ID, wPartID,
                        wPartPointID,
                        WMSPickDemandSourceType.Plan_Out.getValue(), wErrorCode);
                if (wWMSPickDemandItem.ID <= 0) {
                    if (apsTaskSteps.size() > 0 && apsTaskSteps.get(0).Status != APSTaskStatus.Done.getValue()) {
                        wRealAddList.addAll(wAddedList.stream().filter(p -> p.PartPointID == wPartPointID)
                                .collect(Collectors.toList()));
                    } else if (apsTaskSteps.size() <= 0) {
                        wRealAddList.addAll(wAddedList.stream().filter(p -> p.PartPointID == wPartPointID)
                                .collect(Collectors.toList()));
                    }
                    continue;
                }
                // 工序完工不做处理
                if (apsTaskSteps.size() > 0 && apsTaskSteps.get(0).Status == APSTaskStatus.Done.getValue()) {
                    continue;
                }

                List<TCMMaterialChangeItems> wPartPointItems = wAddedList.stream()
                        .filter(p -> p.PartPointID == wPartPointID).collect(Collectors.toList());

                switch (WMSPickDemandStatusNew.getEnumType(wWMSPickDemandItem.ParentStatus)) {
                    case Saved:// 保存状态→原单增加明细行
                        AddDetailRow(wLoginUser, wWMSPickDemandItem, wPartPointItems, wOrder, wMaterialTypeMap,
                                wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
                        break;
                    case NotStart:// 未开始→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                    case Running:// 进行中→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                    case Finished:// 已完成→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                    case FinishClosed:// 完工关闭→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                    case Canceld:// 已取消→创建新的物料配送单，明细行为新增的物料，配送单来源为工艺变更
                        wRealAddList.addAll(wPartPointItems);
                        break;
                    default:
                        break;
                }
            }

            // 创建新的配送单和明细
            if (wRealAddList.size() <= 0) {
                return;
            }

            // 读取系统配置，只生成配置的相关工位
            String wOutLLParts = MESSystemConfigDAO.getInstance().SelectValueByKey(wLoginUser,
                    "Out.LL.Parts", wErrorCode);
            List<Integer> wOutLLPartsList = StringUtils.parseIntList(wOutLLParts.split(","));
            if (wOutLLPartsList.stream().anyMatch(p -> p.intValue() == wPartID)
                    || wOutLLPartsList.size() == 0) {
                // 创建新的物料配送单
                CreateNewPickDemand_Out(wLoginUser, wRealAddList, wTCMTechChangeNotice, wOrder, wPartID,
                        wMaterialTypeMap,
                        wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 创建新的配送单
     */
    private void CreateNewPickDemand(BMSEmployee wLoginUser, List<TCMMaterialChangeItems> wRealAddList,
                                     TCMTechChangeNotice wTCMTechChangeNotice, OMSOrder wOrder, int wPartID,
                                     Map<Integer, Integer> wMaterialTypeMap,
                                     Map<Integer, Double> wMaterialPackMap, boolean wIsSendRecoilMaterial,
                                     OutResult<Integer> wErrorCode) {
        try {
            List<WMSPickDemandItem> wItemList = GetItemList(wLoginUser, wOrder, wTCMTechChangeNotice, wPartID, wMaterialTypeMap,
                    wMaterialPackMap, wIsSendRecoilMaterial, wRealAddList);

            //是否拆分客供料
            boolean wIsSplitCustomerMaterial = MESSystemConfigDAO.getInstance().SelectValueByKey(wLoginUser,
                    "wms.split.customer.demand", wErrorCode).equals("1");

            // 反冲料逻辑处理
            if (!wIsSendRecoilMaterial) {
                List<Integer> wFCList = new ArrayList<>();
                for (int wMaterialID : wMaterialTypeMap.keySet()) {
                    int wType = wMaterialTypeMap.get(wMaterialID);
                    if (wType == MSSMaterialType.RecoilMaterial.getValue()) {
                        wFCList.add(wMaterialID);
                    }
                }

                //拆分反冲料
                List<WMSPickDemandItem> wRecoilList = wItemList.stream().filter(p -> wFCList.stream().anyMatch(q -> q == p.MaterialID)).collect(Collectors.toList());
                if (wRecoilList.size() > 0) {
                    CreateNewPickDemand_Recoil(wLoginUser, wRecoilList, wTCMTechChangeNotice, wOrder, wPartID, wMaterialTypeMap, wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
                }

                wItemList.removeIf(p -> wFCList.stream().anyMatch(q -> q == p.MaterialID));
                if (wItemList.size() <= 0) {
                    return;
                }
            }

            //客供料逻辑处理
            if (wIsSplitCustomerMaterial) {
                List<WMSPickDemandItem> wCustomerMaterialList = wItemList.stream().filter(p -> p.IsCustomerMaterial == 1).collect(Collectors.toList());
                if (wCustomerMaterialList.size() > 0) {
                    CreateNewPickDemand_Customer(wLoginUser, wCustomerMaterialList, wTCMTechChangeNotice, wOrder, wPartID, wMaterialTypeMap, wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
                }

                wItemList.removeIf(p -> p.IsCustomerMaterial == 1);
                if (wItemList.size() <= 0) {
                    return;
                }
            }

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            String wCode = WMSPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);
            Calendar wTime = Calendar.getInstance();

            Calendar expectTime1 = Calendar.getInstance();
            expectTime1.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 0, 0, 0);

            Calendar expectTime2 = Calendar.getInstance();
            expectTime2.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 12, 0, 0);

            // 预计送达日期取周计划的时间
            List<APSTaskPart> apsTaskParts = APSTaskPartDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID, -1,
                    -1, wPartID, 1, APSShiftPeriod.Week.getValue(), null, -1, null, null, wErrorCode);
            if (apsTaskParts != null && apsTaskParts.size() > 0) {
                expectTime1 = apsTaskParts.get(0).StartTime;
                expectTime2 = apsTaskParts.get(0).EndTime;
            }

            String monitorNo = "";
            String monitor = "";
            BMSEmployee wUser = WMSPickDemandDAO.getInstance().GetMonitorByPart(wLoginUser, wPartID,
                    wErrorCode);
            if (StringUtils.isNotEmpty(wUser.LoginID)) {
                monitorNo = wUser.LoginID;
                monitor = wUser.Name;
            }

            WMSPickDemand wWMSPickDemand = new WMSPickDemand(0, "1900",
                    String.valueOf(WMSOrderType.LineOrder.getValue()), wCode, expectTime1, expectTime2, monitorNo,
                    monitor, wOrder.ProductID, wOrder.ProductNo,
                    wOrder.LineID, wOrder.LineName, wOrder.CustomerID,
                    wOrder.Customer,
                    APSConstans.GetCRMCustomer(wOrder.CustomerID).CustomerCode, wOrder.ID,
                    wOrder.PartNo, wPartID, APSConstans.GetFPCPartName(wPartID),
                    APSConstans.GetFPCPart(wPartID).Code, "", "", wBaseTime, "", "", wBaseTime, 1,
                    wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(), wOrder.OrderNo, wBaseTime);
            wWMSPickDemand.SourceType = WMSPickDemandSourceType.TechChange.getValue();
            wWMSPickDemand.TechChangeID = wTCMTechChangeNotice.ID;
            wWMSPickDemand.TechChangeNo = wTCMTechChangeNotice.Code;
            wWMSPickDemand.SourceID = wTCMTechChangeNotice.ID;
            wWMSPickDemand.SourceCode = wTCMTechChangeNotice.Code;

            // 赋值子项
            wWMSPickDemand.ItemList = wItemList;

            // ⑥生成配送单
            if (wWMSPickDemand.ItemList != null && wWMSPickDemand.ItemList.size() > 0) {
                int wNewTaskID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wWMSPickDemand, wErrorCode);
                if (wNewTaskID > 0) {
                    int wIndex = 1;
                    for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                        double wOriFQTY = wWMSPickDemandItem.FQTY;
                        wWMSPickDemandItem.RowNo = String.valueOf(wIndex++);
                        wWMSPickDemandItem.DemandID = wNewTaskID;

                        int wMaterialType = 0;
                        if (wMaterialTypeMap.containsKey(wWMSPickDemandItem.MaterialID)) {
                            wMaterialType = wMaterialTypeMap.get(wWMSPickDemandItem.MaterialID);
                        }
                        double wFQTY = 0;
                        if (wMaterialPackMap.containsKey(wWMSPickDemandItem.MaterialID)
                                && wMaterialType == MSSMaterialType.RecoilMaterial.getValue()
                                && wIsSendRecoilMaterial) {
                            double wMinPack = wMaterialPackMap.get(wWMSPickDemandItem.MaterialID);
                            if (wMinPack > 0) {
                                int wAreaID = APSUtils.getInstance().GetAreaID(wWMSPickDemandItem.PartID);
                                wFQTY = WMSServiceImpl.getInstance().WMS_GetRealLLNumber(wLoginUser, wMinPack,
                                        wWMSPickDemandItem.MaterialID, wWMSPickDemandItem.FQTY, wAreaID,
                                        wErrorCode).Result;
                                wWMSPickDemandItem.FQTY = wFQTY;
                            }
                        }

                        int wItemID = WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem,
                                wErrorCode);

                        // 计算得出不需要领料的，线边库领料->erp过账
                        if (wWMSPickDemandItem.FQTY < wOriFQTY && wItemID > 0) {
                            WMSServiceImpl.getInstance().WMS_RecoilMaterialUse(wLoginUser, wItemID);
                        }
                    }
                    // 推送至wms
                    WMSServiceImpl.getInstance().WMS_ManualPush(wLoginUser, wNewTaskID);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 创建新的配送单（反冲）
     */
    private void CreateNewPickDemand_Recoil(BMSEmployee wLoginUser, List<WMSPickDemandItem> wRecoilList,
                                            TCMTechChangeNotice wTCMTechChangeNotice, OMSOrder wOrder, int wPartID,
                                            Map<Integer, Integer> wMaterialTypeMap,
                                            Map<Integer, Double> wMaterialPackMap, boolean wIsSendRecoilMaterial,
                                            OutResult<Integer> wErrorCode) {
        try {
            // ①读取配置，判断是否需要拆分反冲需求
            String wSplit = MESSystemConfigDAO.getInstance().SelectValueByKey(BaseDAO.SysAdmin,
                    "wms.split.recoil.demand", wErrorCode);
            if (StringUtils.isEmpty(wSplit)) {
                logger.info("未配置是否需要拆分反冲需求!");
                return;
            }

            List<WMSPickDemandItem> wItemList = wRecoilList;

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            String wCode = WMSPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);
            Calendar wTime = Calendar.getInstance();

            Calendar expectTime1 = Calendar.getInstance();
            expectTime1.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 0, 0, 0);

            Calendar expectTime2 = Calendar.getInstance();
            expectTime2.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 12, 0, 0);

            // 预计送达日期取周计划的时间
            List<APSTaskPart> apsTaskParts = APSTaskPartDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID, -1,
                    -1, wPartID, 1, APSShiftPeriod.Week.getValue(), null, -1, null, null, wErrorCode);
            if (apsTaskParts != null && apsTaskParts.size() > 0) {
                expectTime1 = apsTaskParts.get(0).StartTime;
                expectTime2 = apsTaskParts.get(0).EndTime;
            }

            String monitorNo = "";
            String monitor = "";
            BMSEmployee wUser = WMSPickDemandDAO.getInstance().GetMonitorByPart(wLoginUser, wPartID,
                    wErrorCode);
            if (StringUtils.isNotEmpty(wUser.LoginID)) {
                monitorNo = wUser.LoginID;
                monitor = wUser.Name;
            }

            WMSPickDemand wWMSPickDemand = new WMSPickDemand(0, "1900",
                    String.valueOf(WMSOrderType.RecoilLL.getValue()), wCode, expectTime1, expectTime2, monitorNo,
                    monitor, wOrder.ProductID, wOrder.ProductNo,
                    wOrder.LineID, wOrder.LineName, wOrder.CustomerID,
                    wOrder.Customer,
                    APSConstans.GetCRMCustomer(wOrder.CustomerID).CustomerCode, wOrder.ID,
                    wOrder.PartNo, wPartID, APSConstans.GetFPCPartName(wPartID),
                    APSConstans.GetFPCPart(wPartID).Code, "", "", wBaseTime, "", "", wBaseTime, 1,
                    wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(), wOrder.OrderNo, wBaseTime);
            wWMSPickDemand.SourceType = WMSPickDemandSourceType.TechChange.getValue();
            wWMSPickDemand.TechChangeID = wTCMTechChangeNotice.ID;
            wWMSPickDemand.TechChangeNo = wTCMTechChangeNotice.Code;
            wWMSPickDemand.SourceID = wTCMTechChangeNotice.ID;
            wWMSPickDemand.SourceCode = wTCMTechChangeNotice.Code;

            // 赋值子项
            wWMSPickDemand.ItemList = wItemList;

            // ⑥生成配送单
            if (wWMSPickDemand.ItemList != null && wWMSPickDemand.ItemList.size() > 0) {
                int wNewTaskID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wWMSPickDemand, wErrorCode);
                if (wNewTaskID > 0) {
                    int wIndex = 1;
                    for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                        double wOriFQTY = wWMSPickDemandItem.FQTY;
                        wWMSPickDemandItem.RowNo = String.valueOf(wIndex++);
                        wWMSPickDemandItem.DemandID = wNewTaskID;
                        WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem,
                                wErrorCode);
                    }
                    // 推送至wms
                    WMSServiceImpl.getInstance().WMS_ManualPush(wLoginUser, wNewTaskID);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 创建新的配送单（客供）
     */
    private void CreateNewPickDemand_Customer(BMSEmployee wLoginUser, List<WMSPickDemandItem> wRecoilList,
                                              TCMTechChangeNotice wTCMTechChangeNotice, OMSOrder wOrder, int wPartID,
                                              Map<Integer, Integer> wMaterialTypeMap,
                                              Map<Integer, Double> wMaterialPackMap, boolean wIsSendRecoilMaterial,
                                              OutResult<Integer> wErrorCode) {
        try {
            // ①读取配置，判断是否需要拆分客供需求
            String wSplit = MESSystemConfigDAO.getInstance().SelectValueByKey(BaseDAO.SysAdmin,
                    "wms.split.customer.demand", wErrorCode);
            if (StringUtils.isEmpty(wSplit)) {
                logger.info("未配置是否需要拆分客供需求!");
                return;
            }

            List<WMSPickDemandItem> wItemList = wRecoilList;

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            String wCode = WMSPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);
            Calendar wTime = Calendar.getInstance();

            Calendar expectTime1 = Calendar.getInstance();
            expectTime1.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 0, 0, 0);

            Calendar expectTime2 = Calendar.getInstance();
            expectTime2.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 12, 0, 0);

            // 预计送达日期取周计划的时间
            List<APSTaskPart> apsTaskParts = APSTaskPartDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID, -1,
                    -1, wPartID, 1, APSShiftPeriod.Week.getValue(), null, -1, null, null, wErrorCode);
            if (apsTaskParts != null && apsTaskParts.size() > 0) {
                expectTime1 = apsTaskParts.get(0).StartTime;
                expectTime2 = apsTaskParts.get(0).EndTime;
            }

            String monitorNo = "";
            String monitor = "";
            BMSEmployee wUser = WMSPickDemandDAO.getInstance().GetMonitorByPart(wLoginUser, wPartID,
                    wErrorCode);
            if (StringUtils.isNotEmpty(wUser.LoginID)) {
                monitorNo = wUser.LoginID;
                monitor = wUser.Name;
            }

            WMSPickDemand wWMSPickDemand = new WMSPickDemand(0, "1900",
                    String.valueOf(WMSOrderType.CustomerLL.getValue()), wCode, expectTime1, expectTime2, monitorNo,
                    monitor, wOrder.ProductID, wOrder.ProductNo,
                    wOrder.LineID, wOrder.LineName, wOrder.CustomerID,
                    wOrder.Customer,
                    APSConstans.GetCRMCustomer(wOrder.CustomerID).CustomerCode, wOrder.ID,
                    wOrder.PartNo, wPartID, APSConstans.GetFPCPartName(wPartID),
                    APSConstans.GetFPCPart(wPartID).Code, "", "", wBaseTime, "", "", wBaseTime, 1,
                    wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(), wOrder.OrderNo, wBaseTime);
            wWMSPickDemand.SourceType = WMSPickDemandSourceType.TechChange.getValue();
            wWMSPickDemand.TechChangeID = wTCMTechChangeNotice.ID;
            wWMSPickDemand.TechChangeNo = wTCMTechChangeNotice.Code;
            wWMSPickDemand.SourceID = wTCMTechChangeNotice.ID;
            wWMSPickDemand.SourceCode = wTCMTechChangeNotice.Code;

            // 赋值子项
            wWMSPickDemand.ItemList = wItemList;

            // ⑥生成配送单
            if (wWMSPickDemand.ItemList != null && wWMSPickDemand.ItemList.size() > 0) {
                int wNewTaskID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wWMSPickDemand, wErrorCode);
                if (wNewTaskID > 0) {
                    int wIndex = 1;
                    for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                        double wOriFQTY = wWMSPickDemandItem.FQTY;
                        wWMSPickDemandItem.RowNo = String.valueOf(wIndex++);
                        wWMSPickDemandItem.DemandID = wNewTaskID;
                        WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem,
                                wErrorCode);
                    }
                    // 推送至wms
                    WMSServiceImpl.getInstance().WMS_ManualPush(wLoginUser, wNewTaskID);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 创建新的配送单
     */
    private void CreateNewPickDemand_Out(BMSEmployee wLoginUser, List<TCMMaterialChangeItems> wRealAddList,
                                         TCMTechChangeNotice wTCMTechChangeNotice, OMSOrder wOrder, int wPartID,
                                         Map<Integer, Integer> wMaterialTypeMap,
                                         Map<Integer, Double> wMaterialPackMap, boolean wIsSendRecoilMaterial,
                                         OutResult<Integer> wErrorCode) {
        try {
            List<WMSPickDemandItem> wItemList = GetItemList(wLoginUser, wOrder, wTCMTechChangeNotice, wPartID, wMaterialTypeMap,
                    wMaterialPackMap, wIsSendRecoilMaterial, wRealAddList);

            //是否拆分客供料
            boolean wIsSplitCustomerMaterial = MESSystemConfigDAO.getInstance().SelectValueByKey(wLoginUser,
                    "wms.split.customer.demand", wErrorCode).equals("1");

            // 反冲料逻辑处理
            if (!wIsSendRecoilMaterial) {
                List<Integer> wFCList = new ArrayList<>();
                for (int wMaterialID : wMaterialTypeMap.keySet()) {
                    int wType = wMaterialTypeMap.get(wMaterialID);
                    if (wType == MSSMaterialType.RecoilMaterial.getValue()) {
                        wFCList.add(wMaterialID);
                    }
                }

                //拆分反冲料
                List<WMSPickDemandItem> wRecoilList = wItemList.stream().filter(p -> wFCList.stream().anyMatch(q -> q == p.MaterialID)).collect(Collectors.toList());
                if (wRecoilList.size() > 0) {
                    CreateNewPickDemand_Recoil(wLoginUser, wRecoilList, wTCMTechChangeNotice, wOrder, wPartID, wMaterialTypeMap, wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
                }

                wItemList.removeIf(p -> wFCList.stream().anyMatch(q -> q == p.MaterialID));
                if (wItemList.size() <= 0) {
                    return;
                }
            }

            //客供料逻辑处理
            if (wIsSplitCustomerMaterial) {
                List<WMSPickDemandItem> wCustomerMaterialList = wItemList.stream().filter(p -> p.IsCustomerMaterial == 1).collect(Collectors.toList());
                if (wCustomerMaterialList.size() > 0) {
                    CreateNewPickDemand_Customer(wLoginUser, wCustomerMaterialList, wTCMTechChangeNotice, wOrder, wPartID, wMaterialTypeMap, wMaterialPackMap, wIsSendRecoilMaterial, wErrorCode);
                }

                wItemList.removeIf(p -> p.IsCustomerMaterial == 1);
                if (wItemList.size() <= 0) {
                    return;
                }
            }

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            String wCode = WMSPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);
            Calendar wTime = Calendar.getInstance();

            Calendar expectTime1 = Calendar.getInstance();
            expectTime1.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 0, 0, 0);

            Calendar expectTime2 = Calendar.getInstance();
            expectTime2.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 12, 0, 0);

            // 预计送达日期取周计划的时间
            List<APSTaskPart> apsTaskParts = APSTaskPartDAO.getInstance().SelectList(wLoginUser, -1, wOrder.ID, -1,
                    -1, wPartID, 1, APSShiftPeriod.Week.getValue(), null, -1, null, null, wErrorCode);
            if (apsTaskParts != null && apsTaskParts.size() > 0) {
                expectTime1 = apsTaskParts.get(0).StartTime;
                expectTime2 = apsTaskParts.get(0).EndTime;
            }

            String monitorNo = "";
            String monitor = "";
            BMSEmployee wUser = WMSPickDemandDAO.getInstance().GetMonitorByPart(wLoginUser, wPartID,
                    wErrorCode);
            if (StringUtils.isNotEmpty(wUser.LoginID)) {
                monitorNo = wUser.LoginID;
                monitor = wUser.Name;
            }

            WMSPickDemand wWMSPickDemand = new WMSPickDemand(0, "1900",
                    String.valueOf(WMSOrderType.OutLL.getValue()), wCode, expectTime1, expectTime2, monitorNo,
                    monitor, wOrder.ProductID, wOrder.ProductNo,
                    wOrder.LineID, wOrder.LineName, wOrder.CustomerID,
                    wOrder.Customer,
                    APSConstans.GetCRMCustomer(wOrder.CustomerID).CustomerCode, wOrder.ID,
                    wOrder.PartNo, wPartID, APSConstans.GetFPCPartName(wPartID),
                    APSConstans.GetFPCPart(wPartID).Code, "", "", wBaseTime, "", "", wBaseTime, 1,
                    wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(), wOrder.OrderNo, wBaseTime);
            wWMSPickDemand.SourceType = WMSPickDemandSourceType.TechChange_Out.getValue();
            wWMSPickDemand.TechChangeID = wTCMTechChangeNotice.ID;
            wWMSPickDemand.TechChangeNo = wTCMTechChangeNotice.Code;
            wWMSPickDemand.SourceID = wTCMTechChangeNotice.ID;
            wWMSPickDemand.SourceCode = wTCMTechChangeNotice.Code;

            // 赋值子项
            wWMSPickDemand.ItemList = wItemList;

            // 反冲不推送
            List<Integer> wFCList = new ArrayList<>();
            for (int wMaterialID : wMaterialTypeMap.keySet()) {
                int wType = wMaterialTypeMap.get(wMaterialID);
                if (wType == MSSMaterialType.RecoilMaterial.getValue()) {
                    wFCList.add(wMaterialID);
                }
            }
            if (!wIsSendRecoilMaterial) {
                wWMSPickDemand.ItemList.removeIf(p -> wFCList.stream().anyMatch(q -> q == p.MaterialID));
            }

            // ⑥生成配送单
            if (wWMSPickDemand.ItemList != null && wWMSPickDemand.ItemList.size() > 0) {
                int wNewTaskID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wWMSPickDemand, wErrorCode);
                if (wNewTaskID > 0) {
                    int wIndex = 1;
                    for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                        double wOriFQTY = wWMSPickDemandItem.FQTY;
                        wWMSPickDemandItem.RowNo = String.valueOf(wIndex++);
                        wWMSPickDemandItem.DemandID = wNewTaskID;

                        int wMaterialType = 0;
                        if (wMaterialTypeMap.containsKey(wWMSPickDemandItem.MaterialID)) {
                            wMaterialType = wMaterialTypeMap.get(wWMSPickDemandItem.MaterialID);
                        }
                        double wFQTY = 0;
                        if (wMaterialPackMap.containsKey(wWMSPickDemandItem.MaterialID)
                                && wMaterialType == MSSMaterialType.RecoilMaterial.getValue()
                                && wIsSendRecoilMaterial) {
                            double wMinPack = wMaterialPackMap.get(wWMSPickDemandItem.MaterialID);
                            if (wMinPack > 0) {
                                int wAreaID = APSUtils.getInstance().GetAreaID(wWMSPickDemandItem.PartID);
                                wFQTY = WMSServiceImpl.getInstance().WMS_GetRealLLNumber(wLoginUser, wMinPack,
                                        wWMSPickDemandItem.MaterialID, wWMSPickDemandItem.FQTY, wAreaID,
                                        wErrorCode).Result;
                                wWMSPickDemandItem.FQTY = wFQTY;
                            }
                        }

                        int wItemID = WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem,
                                wErrorCode);

                        // 计算得出不需要领料的，线边库领料->erp过账
                        if (wWMSPickDemandItem.FQTY < wOriFQTY && wItemID > 0) {
                            WMSServiceImpl.getInstance().WMS_RecoilMaterialUse(wLoginUser, wItemID);
                        }
                    }
                    // 推送至wms
                    WMSServiceImpl.getInstance().WMS_ManualPush(wLoginUser, wNewTaskID);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 获取配送新单明细
     */
    private List<WMSPickDemandItem> GetItemList(BMSEmployee wLoginUser, OMSOrder wOrder,
                                                TCMTechChangeNotice wTCMTechChangeNotice, int wPartID, Map<Integer, Integer> wMaterialTypeMap,
                                                Map<Integer, Double> wMaterialPackMap, boolean wIsSendRecoilMaterial,
                                                List<TCMMaterialChangeItems> wRealAddList) {
        List<WMSPickDemandItem> wResult = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            int wIndex = 1;
            for (TCMMaterialChangeItems wTCMMaterialChangeItems : wRealAddList) {

                double wFQTY = wTCMMaterialChangeItems.MaterialNumber;
                // 查询台车BOMID
                int wBOMID = APSBOMItemDAO.getInstance().SelectIDBySourceAndMaterial_TechChange(wLoginUser, wOrder.ID,
                        wTCMMaterialChangeItems.MaterialID, wTCMMaterialChangeItems.PlaceID,
                        wTCMMaterialChangeItems.PartPointID, wErrorCode);
                if (wBOMID <= 0) {
                    wBOMID = APSBOMItemDAO.getInstance().SelectIDBySourceAndMaterial_TechChange_NoSource(wLoginUser,
                            wOrder.ID,
                            wTCMMaterialChangeItems.MaterialID, wTCMMaterialChangeItems.PlaceID,
                            wTCMMaterialChangeItems.PartPointID, wErrorCode);
                }
                if (wBOMID > 0) {
                    APSBOMItem wAPSBOMItem = APSBOMItemDAO.getInstance().SelectByID(wLoginUser, wBOMID, wErrorCode);
                    WMSPickDemandItem wWMSPickDemandItem = new WMSPickDemandItem(0, 0,
                            wTCMMaterialChangeItems.MaterialID, wTCMMaterialChangeItems.MaterialNo,
                            wTCMMaterialChangeItems.MaterialName,
                            wTCMMaterialChangeItems.MaterialNumber, wOrder.OrderNo, wTCMMaterialChangeItems.PartPointID,
                            APSConstans.GetFPCPartPoint(wTCMMaterialChangeItems.PartPointID).Code.replace("PS-", ""),
                            APSConstans.GetFPCPartPointName(wTCMMaterialChangeItems.PartPointID),
                            String.valueOf(wIndex++), "",
                            wTCMMaterialChangeItems.ReplaceType,
                            SFCReplaceType.getEnumType(wTCMMaterialChangeItems.ReplaceType).getLable(),
                            wTCMMaterialChangeItems.OutsourceType,
                            SFCOutSourceType.getEnumType(wTCMMaterialChangeItems.OutsourceType).getLable(),
                            "常规新件", "", wBaseTime, wPartID,
                            0, wFQTY, wAPSBOMItem.OrderNum);
                    wWMSPickDemandItem.IsOriDis = wAPSBOMItem.OriginalType == 1 ? "是" : "否";
                    wWMSPickDemandItem.IsCustomerMaterial = wAPSBOMItem.CustomerMaterial;

                    wResult.add(wWMSPickDemandItem);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 原单增加明细行
     */
    private synchronized void AddDetailRow(BMSEmployee wLoginUser, WMSPickDemandItem wWMSPickDemandItemOri,
                                           List<TCMMaterialChangeItems> wPartPointItems, OMSOrder wOrder,
                                           Map<Integer, Integer> wMaterialTypeMap,
                                           Map<Integer, Double> wMaterialPackMap, boolean wIsSendRecoilMaterial,
                                           OutResult<Integer> wErrorCode) {
        try {
            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            List<WMSPickDemandItem> wmsPickDemandItems = WMSPickDemandItemDAO.getInstance().SelectList(wLoginUser, -1,
                    wWMSPickDemandItemOri.DemandID, -1, "", -1, wErrorCode);
            int wRowNo = StringUtils.parseInt(wmsPickDemandItems.get(wmsPickDemandItems.size() - 1).RowNo) + 1;
            for (TCMMaterialChangeItems wTCMMaterialChangeItems : wPartPointItems) {

                double wFQTY = wTCMMaterialChangeItems.MaterialNumber;
                // 查询台车BOMID
                int wBOMID = APSBOMItemDAO.getInstance().SelectIDBySourceAndMaterial_TechChange(wLoginUser, wOrder.ID,
                        wTCMMaterialChangeItems.MaterialID, wTCMMaterialChangeItems.PlaceID,
                        wTCMMaterialChangeItems.PartPointID, wErrorCode);
                if (wBOMID <= 0) {
                    wBOMID = APSBOMItemDAO.getInstance().SelectIDBySourceAndMaterial_TechChange_NoSource(wLoginUser,
                            wOrder.ID,
                            wTCMMaterialChangeItems.MaterialID, wTCMMaterialChangeItems.PlaceID,
                            wTCMMaterialChangeItems.PartPointID, wErrorCode);
                }
                if (wBOMID > 0) {
                    APSBOMItem wAPSBOMItem = APSBOMItemDAO.getInstance().SelectByID(wLoginUser, wBOMID, wErrorCode);
                    WMSPickDemandItem wWMSPickDemandItem = new WMSPickDemandItem(0, 0,
                            wTCMMaterialChangeItems.MaterialID, wTCMMaterialChangeItems.MaterialNo,
                            wTCMMaterialChangeItems.MaterialName,
                            wTCMMaterialChangeItems.MaterialNumber, wOrder.OrderNo, wTCMMaterialChangeItems.PartPointID,
                            APSConstans.GetFPCPartPoint(wTCMMaterialChangeItems.PartPointID).Code.replace("PS-", ""),
                            APSConstans.GetFPCPartPointName(wTCMMaterialChangeItems.PartPointID), "0", "",
                            wTCMMaterialChangeItems.ReplaceType,
                            SFCReplaceType.getEnumType(wTCMMaterialChangeItems.ReplaceType).getLable(),
                            wTCMMaterialChangeItems.OutsourceType,
                            SFCOutSourceType.getEnumType(wTCMMaterialChangeItems.OutsourceType).getLable(),
                            "常规新件", "", wBaseTime, wWMSPickDemandItemOri.PartID,
                            0, wFQTY, wAPSBOMItem.OrderNum);

                    wWMSPickDemandItem.IsOriDis = wAPSBOMItem.OriginalType == 1 ? "是" : "否";

                    int wIndex = wRowNo;
                    double wOriFQTY = wWMSPickDemandItem.FQTY;
                    wWMSPickDemandItem.RowNo = String.valueOf(wIndex++);
                    wWMSPickDemandItem.DemandID = wWMSPickDemandItemOri.DemandID;

                    int wMaterialType = 0;
                    if (wMaterialTypeMap.containsKey(wWMSPickDemandItem.MaterialID)) {
                        wMaterialType = wMaterialTypeMap.get(wWMSPickDemandItem.MaterialID);
                    }
                    wFQTY = 0;
                    if (wMaterialPackMap.containsKey(wWMSPickDemandItem.MaterialID)
                            && wMaterialType == MSSMaterialType.RecoilMaterial.getValue()
                            && wIsSendRecoilMaterial) {
                        double wMinPack = wMaterialPackMap.get(wWMSPickDemandItem.MaterialID);
                        if (wMinPack > 0) {
                            int wAreaID = APSUtils.getInstance().GetAreaID(wWMSPickDemandItem.PartID);
                            wFQTY = WMSServiceImpl.getInstance().WMS_GetRealLLNumber(wLoginUser, wMinPack,
                                    wWMSPickDemandItem.MaterialID, wWMSPickDemandItem.FQTY, wAreaID,
                                    wErrorCode).Result;
                            wWMSPickDemandItem.FQTY = wFQTY;
                        }
                    }

                    int wItemID = WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem,
                            wErrorCode);

                    // 计算得出不需要领料的，线边库领料->erp过账
                    if (wWMSPickDemandItem.FQTY < wOriFQTY && wItemID > 0) {
                        WMSServiceImpl.getInstance().WMS_RecoilMaterialUse(wLoginUser, wItemID);
                    }
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 获取工序作业人员
     */
    private List<Integer> GetUserListByOrderIDAndPartPointID(BMSEmployee wLoginUser, int wOrderID, int wPartPointID) {
        List<Integer> wResult = new ArrayList<Integer>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            wResult = SFCTaskStepDAO.getInstance().SelectUserIDListByOrderIDAndPartPointID(wLoginUser, wOrderID,
                    wPartPointID, wErrorCode);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public WMSLinePartLLCancel GetWMSLinePartLLCancel(WMSPickDemand wWMSPickDemand) {
        WMSLinePartLLCancel wResult = new WMSLinePartLLCancel();
        try {
            wResult = new WMSLinePartLLCancel(wWMSPickDemand.OrderType, "WH01", "1900", wWMSPickDemand.DemandNo);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public WMSLinePartLLCancel GetWMSLinePartLLCancel(WMSBatchPickDemand wWMSBatchPickDemand) {
        WMSLinePartLLCancel wResult = new WMSLinePartLLCancel();
        try {
            wResult = new WMSLinePartLLCancel(wWMSBatchPickDemand.OrderType, "WH01", "1900",
                    wWMSBatchPickDemand.DemandNo);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public void WMS_TaskStepCancelTechChange(BMSEmployee wLoginUser, APSTaskStepCancelLogBPM wData) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSPickDemand> wDemandList = WMSPickDemandDAO.getInstance().SelectList(wLoginUser, -1,
                    String.valueOf(WMSOrderType.LineOrder.getValue()), "", -1, -1, -1, String.valueOf(wData.OrderID),
                    wData.PartID, -1,
                    null, null, null, wErrorCode);
            if (wDemandList == null || wDemandList.size() <= 0) {
                return;
            }

            String[] wStrs = wData.StepIDs.split(",");
            List<Integer> wStepIDList = new ArrayList<>();
            for (String wString : wStrs) {
                int wStepID = StringUtils.parseInt(wString);
                if (wStepID > 0 && wStepIDList.stream().noneMatch(p -> p == wStepID)) {
                    wStepIDList.add(wStepID);
                }
            }

            List<WMSPickDemand> wList = new ArrayList<>();
            for (WMSPickDemand wWMSPickDemand : wDemandList) {
                List<WMSPickDemandItem> wItemList = WMSPickDemandItemDAO.getInstance().SelectList(wLoginUser, -1,
                        wWMSPickDemand.ID, -1, "", -1, wErrorCode);
                if (wItemList == null || wItemList.size() <= 0) {
                    continue;
                }
                if (wItemList.stream()
                        .noneMatch(p -> wStepIDList.stream().anyMatch(q -> q == p.PartPointID))) {
                    continue;
                }
                wWMSPickDemand.ItemList = wItemList;
                wList.add(wWMSPickDemand);
            }

            for (WMSPickDemand wWMSPickDemand : wList) {
                switch (WMSPickDemandStatus.getEnumType(wWMSPickDemand.Status)) {
                    case Saved:// ①未推送，删除数据，删除物料需求计划
                        WMS_TaskStepCancelTechChange_Saved(wWMSPickDemand, wStepIDList, wData);
                        break;
                    case Sended:// ①未分拣：取消配送单，生成新单；
                        WMS_TaskStepCancelTechChange_Sended(wWMSPickDemand, wData, wStepIDList);
                        break;
                    case Picked:// ②已分拣，对应条目标注状态，库房交接时执行退料；
                    case Checked:
                    case Received:
                        WMS_TaskStepCancelTechChange_Picked(wWMSPickDemand, wStepIDList);
                        break;
                    default:
                        break;
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 已分拣，对应条目标注状态，库房交接时执行退料；
     */
    private void WMS_TaskStepCancelTechChange_Picked(WMSPickDemand wWMSPickDemand, List<Integer> wStepIDList) {
        try {
            wWMSPickDemand.ItemList
                    .removeIf(p -> p.PickedNumber <= 0 || wStepIDList.stream().noneMatch(q -> q == p.PartPointID));
            for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                APSMaterialReturn wAPSMaterialReturn = new APSMaterialReturn();
                wAPSMaterialReturn.ID = 0;
                wAPSMaterialReturn.BOMType = 2;
                wAPSMaterialReturn.FactoryID = 1900;
                wAPSMaterialReturn.WBSNo = wWMSPickDemand.WBSNo;
                wAPSMaterialReturn.OrderID = wWMSPickDemand.OrderID;
                wAPSMaterialReturn.PartNo = wWMSPickDemand.PartNo;
                wAPSMaterialReturn.LineID = wWMSPickDemand.LineID;
                wAPSMaterialReturn.ProductID = wWMSPickDemand.ProductID;
                wAPSMaterialReturn.CustomerID = wWMSPickDemand.CustomerID;
                wAPSMaterialReturn.PartID = wWMSPickDemand.PartID;
                wAPSMaterialReturn.PartPointID = wWMSPickDemandItem.PartPointID;
                wAPSMaterialReturn.MaterialID = wWMSPickDemandItem.MaterialID;
                wAPSMaterialReturn.MaterialNo = wWMSPickDemandItem.MaterialNo;
                wAPSMaterialReturn.MaterialName = wWMSPickDemandItem.MaterialName;
                wAPSMaterialReturn.Number = wWMSPickDemandItem.FQTY;
                wAPSMaterialReturn.UnitID = APSConstans.GetCFGUnit(wWMSPickDemandItem.UnitText).ID;
                wAPSMaterialReturn.ReplaceType = wWMSPickDemandItem.ReplaceType;
                wAPSMaterialReturn.OutsourceType = wWMSPickDemandItem.OutSourceType;
                wAPSMaterialReturn.ReceiveDepart = "0001";
                wAPSMaterialReturn.StockID = 1200;
                wAPSMaterialReturn.EditorID = BaseDAO.SysAdmin.ID;
                wAPSMaterialReturn.EditTime = Calendar.getInstance();
                wAPSMaterialReturn.Status = 1;
                wAPSMaterialReturn.AssessmentType = "";
                if (wAPSMaterialReturn.ReplaceType == 1) {
                    wAPSMaterialReturn.AssessmentType = "常规新件";
                } else if (wAPSMaterialReturn.OutsourceType == 1) {
                    wAPSMaterialReturn.AssessmentType = "修复旧件";
                } else {
                    wAPSMaterialReturn.AssessmentType = "常规新件";
                }
                wAPSMaterialReturn.Remark = "工序取消";
                wAPSMaterialReturn.SourceType = 2;
                wAPSMaterialReturn.SourceID = wWMSPickDemandItem.ID;
                wAPSMaterialReturn.DemandID = wWMSPickDemandItem.DemandID;
                wAPSMaterialReturn.DemandItemID = wWMSPickDemandItem.ID;

                QMSServiceImpl.getInstance().APS_UpdateMaterialReturn(BaseDAO.SysAdmin, wAPSMaterialReturn);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 未分拣：取消配送单，生成新单；
     */
    private void WMS_TaskStepCancelTechChange_Sended(WMSPickDemand wDemand, APSTaskStepCancelLogBPM wData,
                                                     List<Integer> wStepIDList) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // 取消配送单
            MyHelperServiceImpl.getInstance().WMS_PostLLCancel(wDemand);
            // 生成新单
            List<WMSPickDemandItem> wItemList = wDemand.ItemList.stream()
                    .filter(p -> wStepIDList.stream().noneMatch(q -> q == p.PartPointID))
                    .collect(Collectors.toList());

            String wCode = WMSPickDemandDAO.getInstance().GetNewCode(BaseDAO.SysAdmin, wErrorCode);
            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            WMSPickDemand wWMSPickDemand = new WMSPickDemand(0, "1900",
                    String.valueOf(WMSOrderType.LineOrder.getValue()), wCode, wDemand.ExpectTime1, wDemand.ExpectTime2,
                    wDemand.MonitorNo, wDemand.Monitor, wDemand.ProductID, wDemand.ProductNo, wDemand.LineID,
                    wDemand.LineName, wDemand.CustomerID, APSConstans.GetCRMCustomer(wDemand.CustomerID).CustomerName,
                    APSConstans.GetCRMCustomer(wDemand.CustomerID).CustomerCode, wDemand.OrderID, wDemand.PartNo,
                    wDemand.PartID, APSConstans.GetFPCPartName(wDemand.PartID),
                    APSConstans.GetFPCPart(wDemand.PartID).Code, "", "", wBaseTime, "", "", wBaseTime, 1,
                    BaseDAO.SysAdmin.ID, BaseDAO.SysAdmin.Name, Calendar.getInstance(), wDemand.WBSNo, wBaseTime);
            wWMSPickDemand.SourceType = WMSPickDemandSourceType.TechChange.getValue();
            wWMSPickDemand.ItemList = wItemList;
            wWMSPickDemand.SourceID = wData.ID;
            wWMSPickDemand.SourceCode = wData.Code;
            int wNewID = WMSPickDemandDAO.getInstance().Update(BaseDAO.SysAdmin, wWMSPickDemand, wErrorCode);
            if (wNewID > 0) {
                wItemList.forEach(p -> {
                    p.DemandID = wNewID;
                    p.ID = 0;
                });
                int wIndex = 1;
                for (WMSPickDemandItem wWMSPickDemandItem : wItemList) {
                    wWMSPickDemandItem.RowNo = String.valueOf(wIndex++);
                    WMSPickDemandItemDAO.getInstance().Update(BaseDAO.SysAdmin, wWMSPickDemandItem, wErrorCode);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 未推送，删除数据，删除物料需求计划
     */
    private void WMS_TaskStepCancelTechChange_Saved(WMSPickDemand wDemand, List<Integer> wStepIDList,
                                                    APSTaskStepCancelLogBPM wData) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①删除明细
            List<WMSPickDemandItem> wDeleteList = wDemand.ItemList.stream()
                    .filter(p -> wStepIDList.stream().anyMatch(q -> q == p.PartPointID))
                    .collect(Collectors.toList());
            WMSPickDemandItemDAO.getInstance().DeleteList(BaseDAO.SysAdmin, wDeleteList, wErrorCode);
            // ②禁用物料需求计划
            for (int wStepID : wStepIDList) {
                List<MRPMaterialPlan> wDisableList = MRPMaterialPlanDAO.getInstance().SelectList(BaseDAO.SysAdmin, -1,
                        -1, -1, -1, wDemand.OrderID, wDemand.PartID, wStepID, -1, "", "", -1, "", 1, -1, -1, null, null,
                        null, null, "", wErrorCode);
                if (wDisableList.size() > 0) {
                    MRPMaterialPlanDAO.getInstance().Active(BaseDAO.SysAdmin,
                            wDisableList.stream().map(p -> p.ID).distinct().collect(Collectors.toList()), 2,
                            wErrorCode);
                }
            }
            // ③更新备注
            wDemand.Remark = "工序取消";
            wDemand.TechChangeID = wData.ID;
            wDemand.TechChangeNo = wData.Code;
            wDemand.Status = WMSPickDemandStatus.Canceled.getValue();
            WMSPickDemandDAO.getInstance().Update(BaseDAO.SysAdmin, wDemand, wErrorCode);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    @Override
    public ServiceResult<Integer> WMS_TriggerMaterialReturn(BMSEmployee wLoginUser, int wOrderID, int wPartID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<MESMaterialReturn>> MES_QueryMaterialReturnList(BMSEmployee wLoginUser, String wAsnType,
                                                                              String wRMaNO, int wProductID,
                                                                              int wLineID, int wCustomerID,
                                                                              int wOrderID, int wPartID, int wStatus,
                                                                              String wMaterial, Calendar wStartTime,
                                                                              Calendar wEndTime, int wUpFlowID) {
        ServiceResult<List<MESMaterialReturn>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<Integer> wTaskIDList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wMaterial)) {
                wTaskIDList = MESMaterialReturnItemDAO.getInstance().SelectTaskIDList(wLoginUser, wMaterial,
                        wErrorCode);
            }

            List<Integer> wStatusList = new ArrayList<>();
            if (wStatus >= 0) {
                wStatusList.add(wStatus);
            }
            wResult.Result = MESMaterialReturnDAO.getInstance().SelectList(wLoginUser, -1, wUpFlowID, wAsnType, wRMaNO,
                    wProductID, wLineID, wCustomerID, wOrderID, wPartID, wStatusList, wStartTime, wEndTime, wTaskIDList,
                    null, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<MESMaterialReturn> MES_QueryMaterialReturn(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<MESMaterialReturn> wResult = new ServiceResult<>();
        wResult.Result = new MESMaterialReturn();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = MESMaterialReturnDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> MES_ManualPushMaterialReturn(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            MESMaterialReturn wTask = MESMaterialReturnDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);
            if (wTask == null || wTask.ID <= 0) {
                wResult.FaultCode += RetCode.SERVER_RST_ERROR_OUT;
                return wResult;
            }

            // WMSLinePartTLs wWMSLinePartTLs = GetWMSLinePartTLs(wTask);
            //
            // WMSReturn wRst =
            // MyHelperServiceImpl.getInstance().WMS_PostTL(wWMSLinePartTLs);
            // if (wRst.returnFlag.equals("1")) {
            // wTask.Remark = "";
            // wTask.Status = MESMaterialReturnStatus.Sended.getValue();
            // } else {
            // wTask.Remark = wRst.returnDesc;
            // wTask.Status = MESMaterialReturnStatus.Failed.getValue();
            // }

            // 测试代码
            wTask.MyRemark = "";
            wTask.Status = MESMaterialReturnStatus.Sended.getValue();

            MESMaterialReturnDAO.getInstance().Update(wLoginUser, wTask, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> MES_BackMaterial(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            MESMaterialReturn wTask = MESMaterialReturnDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);
            if (wTask == null || wTask.ID <= 0) {
                wResult.FaultCode += RetCode.SERVER_RST_ERROR_OUT;
                return wResult;
            }

            wTask.Status = MESMaterialReturnStatus.Backed.getValue();
            wTask.BackTime = Calendar.getInstance();
            MESMaterialReturnDAO.getInstance().Update(wLoginUser, wTask, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Double> WMS_GetRealLLNumber(BMSEmployee wLoginUser, double wMinPack, int wMaterialID,
                                                     double wNeedNumber, int wAreaID, OutResult<Integer> wErrorCode) {
        ServiceResult<Double> wResult = new ServiceResult<>(0.0);
        try {
            // 在反冲料领料时先去线边库查询库存是否满足要料需求，这里的线边库存包括（实际已接收入库库存+已提交至WMS未接收库存（在途库存））的和，
            // 这样计算的结果才是发至WMS的领料数量。
            double wRealKC = 0.0;
            List<WMSLineEdgeLibrary> wList = WMSLineEdgeLibraryDAO.getInstance().SelectList(wLoginUser, -1, wMaterialID,
                    "", null, null, wAreaID, 1, "", wErrorCode);
            for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wList) {
                wRealKC += wWMSLineEdgeLibrary.FQTY;
            }
            // 查询在途库存
            if (wRealKC >= wNeedNumber) {
                wResult.Result = 0.0;
                return wResult;
            }

            double wRealNeedNumber = wNeedNumber - wRealKC;

            if (wMinPack <= 0) {
                wResult.Result = wRealNeedNumber;
            } else {
                int wSize = (int) (wRealNeedNumber / wMinPack);
                wResult.Result = wRealNeedNumber % wMinPack == 0 ? wSize * wMinPack : (wSize + 1) * wMinPack;
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSLineEdgeLibrary>> WMS_QueryLineEdgeLibraryList(BMSEmployee wLoginUser,
                                                                                String wMaterial, Calendar wStartTime, Calendar wEndTime, int wSourceType,
                                                                                int wAreaID, String wBatchNumber) {
        ServiceResult<List<WMSLineEdgeLibrary>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSLineEdgeLibraryDAO.getInstance().SelectList(wLoginUser, -1, -1, wMaterial, wStartTime,
                    wEndTime, wAreaID, wSourceType, wBatchNumber, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSLineEdgeLibrary> WMS_QueryLineEdgeLibrary(BMSEmployee wLoginUser, int wWMSLineEdgeID) {
        ServiceResult<WMSLineEdgeLibrary> wResult = new ServiceResult<>();
        wResult.Result = new WMSLineEdgeLibrary();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser, wWMSLineEdgeID, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_TestReport(BMSEmployee wLoginUser, int wItemID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSPickDemand>> WMS_QueryPickDemandEmployeeAll(BMSEmployee wLoginUser, int wTagType,
                                                                             Calendar wStartTime, Calendar wEndTime) {
        ServiceResult<List<WMSPickDemand>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            switch (wTagType) {
                case 1:
                    List<Integer> wTaskIDList = BFCMessageDAO.getInstance().BFC_QueryMessageIDToDoList(wLoginUser,
                            BPMEventModule.MaterialSend.getValue(), wErrorCode);
                    if (wTaskIDList.size() > 0) {
                        wResult.Result = WMSPickDemandDAO.getInstance().SelectList(wLoginUser, -1, "", "", -1, -1, -1,
                                "",
                                -1, -1, null, null, wTaskIDList, wErrorCode);
                        // 剔除掉单据状态为`完工关闭`的单子
                        if (wResult.Result.size() > 0) {
                            wResult.Result.removeIf(p -> p.Status == WMSPickDemandStatusNew.FinishClosed.getValue());
                        }
                    }
                    break;
                case 2:
                    wResult.Result = WMSPickDemandDAO.getInstance().SelectTaskDoneList(wLoginUser, wStartTime, wEndTime,
                            wErrorCode);
                    break;
                default:
                    break;
            }

            // 按照车型、车号、工位排序（首先按照`分拣时间`倒序排序）
            if (wResult.Result.size() > 0) {
                wResult.Result.sort(Comparator.comparing(WMSPickDemand::getSorterTime, Comparator.reverseOrder())
                        .thenComparing(WMSPickDemand::getProductNo)
                        .thenComparing(WMSPickDemand::getPartNo)
                        .thenComparing(WMSPickDemand::getPartCode));
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<MESMaterialReturn>> MES_QueryMaterialReturnListEmployeeAllWeb(BMSEmployee wLoginUser,
                                                                                            String wAsnType,
                                                                                            String wCode,
                                                                                            int wProductID,
                                                                                            int wLineID,
                                                                                            int wCustomerID,
                                                                                            int wOrderID,
                                                                                            int wPartID,
                                                                                            String wMaterial,
                                                                                            Calendar wStartTime,
                                                                                            Calendar wEndTime,
                                                                                            int wStatus) {
        ServiceResult<List<MESMaterialReturn>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            List<Integer> wTaskIDList = new ArrayList<>();
            if (StringUtils.isNotEmpty(wMaterial)) {
                wTaskIDList = MESMaterialReturnItemDAO.getInstance().SelectTaskIDList(wLoginUser, wMaterial,
                        wErrorCode);
            }

            switch (wStatus) {
                case 1:
                    wResult.Result.addAll(MESMaterialReturnDAO.getInstance().SelectList(wLoginUser, -1, -1, wAsnType,
                            wCode,
                            wProductID, wLineID, wCustomerID, wOrderID, wPartID,
                            StringUtils.parseListArgs(25), wStartTime, wEndTime,
                            wTaskIDList, null, wErrorCode));
                    break;
                case 0:
                    wResult.Result.addAll(MESMaterialReturnDAO.getInstance().SelectList(wLoginUser, -1, -1, wAsnType,
                            wCode,
                            wProductID, wLineID, wCustomerID, wOrderID, wPartID, null, null, null, wTaskIDList,
                            StringUtils.parseListArgs(0, 21, 22, 25),
                            wErrorCode));
                    break;
                default:
                    wResult.Result.addAll(MESMaterialReturnDAO.getInstance().SelectList(wLoginUser, -1, -1, wAsnType,
                            wCode,
                            wProductID, wLineID, wCustomerID, wOrderID, wPartID,
                            StringUtils.parseListArgs(21, 22, 25), wStartTime, wEndTime,
                            wTaskIDList, null, wErrorCode));
                    wResult.Result.addAll(MESMaterialReturnDAO.getInstance().SelectList(wLoginUser, -1, -1, wAsnType,
                            wCode,
                            wProductID, wLineID, wCustomerID, wOrderID, wPartID, null, null, null, wTaskIDList,
                            StringUtils.parseListArgs(0, 21, 22, 25),
                            wErrorCode));
                    break;
            }
            wResult.Result.sort((o1, o2) -> o2.SubmitTime.compareTo(o1.SubmitTime));

            if (wResult.Result.size() <= 0 || wStatus == 1) {
                return wResult;
            }

            List<BPMTaskBase> wBaseList = MESMaterialReturnDAO.getInstance().BPM_GetUndoTaskList(wLoginUser,
                    wLoginUser.ID, wErrorCode);

            if (wBaseList == null || wBaseList.size() <= 0) {
                return wResult;
            }
            for (BPMTaskBase wTaskBase : wBaseList) {
                if (!(wTaskBase instanceof MESMaterialReturn))
                    continue;
                MESMaterialReturn wMESMaterialReturn = (MESMaterialReturn) wTaskBase;
                wMESMaterialReturn.TagTypes = TaskQueryType.ToHandle.getValue();
                for (int i = 0; i < wResult.Result.size(); i++) {
                    if (wResult.Result.get(i).ID == wMESMaterialReturn.ID)
                        wResult.Result.set(i, wMESMaterialReturn);
                }
            }
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_CreateOutRepairReceipt(BMSEmployee wLoginUser,
                                                             List<IPTOutsourcingMaterial> wList) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // 创建送修单
            String monitorNo = "";
            String monitor = "";
            BMSEmployee wUser = WMSPickDemandDAO.getInstance().GetMonitorByPart(wLoginUser, wList.get(0).PartID,
                    wErrorCode);
            if (StringUtils.isNotEmpty(wUser.LoginID)) {
                monitorNo = wUser.LoginID;
                monitor = wUser.Name;
            }

            List<Integer> wMaterialIDList = wList.stream()
                    .map(p -> p.MaterialID)
                    .distinct().collect(Collectors.toList());
            // 获取物料最小包装字典
            Map<Integer, Double> wMaterialPackMap = MRPMaterialPlanDAO.getInstance().GetMaterialPackMap(wLoginUser,
                    wMaterialIDList, wErrorCode);

            // 获取反冲物料列表
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            boolean wIsChangeFQTY = Configuration.readConfigString("IsSendRecoilMaterial", "config/config").equals("1");

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);
            String wCode = WMSPickDemandDAO.getInstance().GetNewCode_Out(wLoginUser, wErrorCode);
            WMSPickDemand wWMSPickDemand = new WMSPickDemand(0, "1900",
                    String.valueOf(WMSOrderType.SubcontractingRepairReceipt.getValue()), wCode, Calendar.getInstance(),
                    Calendar.getInstance(), monitorNo, monitor, wList.get(0).ProductID, wList.get(0).ProductNo,
                    wList.get(0).LineID, wList.get(0).LineName, wList.get(0).CustomerID,
                    APSConstans.GetCRMCustomer(wList.get(0).CustomerID).CustomerName,
                    APSConstans.GetCRMCustomer(wList.get(0).CustomerID).CustomerCode, wList.get(0).OrderID,
                    wList.get(0).PartNo, wList.get(0).PartID, APSConstans.GetFPCPartName(wList.get(0).PartID),
                    APSConstans.GetFPCPart(wList.get(0).PartID).Code, "", "", wBaseTime, "", "", wBaseTime, 1,
                    wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(), wList.get(0).WBSNo, wBaseTime);
            int wDemandID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wWMSPickDemand, wErrorCode);
            if (wDemandID > 0) {
                wWMSPickDemand.ID = wDemandID;
                for (IPTOutsourcingMaterial wIPTOutsourcingMaterial : wList) {
                    wIPTOutsourcingMaterial.Status = IPTOutsourcingMaterialStatus.ReceiptDocCreated.getValue();
                    wIPTOutsourcingMaterial.DemandID = wDemandID;
                    IPTOutsourcingMaterialDAO.getInstance().Update(wLoginUser, wIPTOutsourcingMaterial, wErrorCode);
                }
                // ④创建领料需求单明细
                int wIndex = 1;
                for (IPTOutsourcingMaterial wIPTOutsourcingMaterial : wList) {

                    double wFQTY = wIPTOutsourcingMaterial.FQTY;
                    int wMaterialType = 0;
                    if (wMaterialTypeMap.containsKey(wIPTOutsourcingMaterial.MaterialID)) {
                        wMaterialType = wMaterialTypeMap.get(wIPTOutsourcingMaterial.MaterialID);
                    }
                    // 根据最小包装计算需求
                    if (wMaterialPackMap.containsKey(wIPTOutsourcingMaterial.MaterialID)
                            && wMaterialType == MSSMaterialType.RecoilMaterial.getValue() && wIsChangeFQTY) {
                        double wMinPack = wMaterialPackMap.get(wIPTOutsourcingMaterial.MaterialID);
                        if (wMinPack > 0) {
                            int wAreaID = APSUtils.getInstance().GetAreaID(wIPTOutsourcingMaterial.PartID);
                            wFQTY = WMSServiceImpl.getInstance().WMS_GetRealLLNumber(wLoginUser, wMinPack,
                                    wIPTOutsourcingMaterial.MaterialID, wIPTOutsourcingMaterial.FQTY, wAreaID,
                                    wErrorCode).Result;
                        }
                    }

                    WMSPickDemandItem wWMSPickDemandItem = new WMSPickDemandItem(0, wDemandID,
                            wIPTOutsourcingMaterial.MaterialID, wIPTOutsourcingMaterial.MaterialNo,
                            wIPTOutsourcingMaterial.MaterialName, wIPTOutsourcingMaterial.FQTY,
                            wIPTOutsourcingMaterial.WBSNo, wIPTOutsourcingMaterial.StepID,
                            APSConstans.GetFPCPartPoint(wIPTOutsourcingMaterial.StepID).Code.replace("PS-", ""),
                            APSConstans.GetFPCPartPointName(wIPTOutsourcingMaterial.StepID), String.valueOf(wIndex), "",
                            0, "", wIPTOutsourcingMaterial.OutSourceType,
                            SFCOutSourceType.getEnumType(wIPTOutsourcingMaterial.OutSourceType).getLable(), "修复旧件", "",
                            wBaseTime, wWMSPickDemand.PartID, 1, wIPTOutsourcingMaterial.FQTY, 0);

//                    wWMSPickDemandItem.IsOriDis=wAPSBOMItem.OriginalType==1?"是":"否";

                    wWMSPickDemandItem.ProductName = wIPTOutsourcingMaterial.SuplierName;
                    wWMSPickDemandItem.Supplier = wIPTOutsourcingMaterial.SuplierNo;
                    wWMSPickDemandItem.SerialNo = wIPTOutsourcingMaterial.SerialNo;
                    wWMSPickDemandItem.OutSourceMaterialID = wIPTOutsourcingMaterial.ID;

                    if (wFQTY > 0) {
                        wWMSPickDemandItem.FQTY = wFQTY;
                    }
                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem, wErrorCode);
                    wIndex++;
                }
                // 创建产线领料单（逻辑已修改，先打开测试用，后面要屏蔽）
                // 委外必修：机车进厂生成台车bom时，自动根据bom生成委外领料单（委外必修），
                // 委外偶修：根据偶换件提报，生成委外领料单（委外偶修）
                // CreateLineMaterialDemand(wLoginUser, wWMSPickDemand, wList);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 创建委外领料单
     */
    private void CreateLineMaterialDemand(BMSEmployee wLoginUser, WMSPickDemand wOutPickDemand,
                                          List<IPTOutsourcingMaterial> wList) {
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            if (wList == null || wList.size() <= 0) {
                return;
            }

            OMSOrder wOMSOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wList.get(0).OrderID, wErrorCode);

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            String wCode = WMSPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);
            Calendar wTime = Calendar.getInstance();

            Calendar expectTime1 = Calendar.getInstance();
            expectTime1.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 0, 0, 0);

            Calendar expectTime2 = Calendar.getInstance();
            expectTime2.set(wTime.get(Calendar.YEAR), wTime.get(Calendar.MONTH), wTime.get(Calendar.DATE), 12, 0, 0);

            String monitorNo = "";
            String monitor = "";
            BMSEmployee wUser = WMSPickDemandDAO.getInstance().GetMonitorByPart(wLoginUser, wList.get(0).PartID,
                    wErrorCode);
            if (StringUtils.isNotEmpty(wUser.LoginID)) {
                monitorNo = wUser.LoginID;
                monitor = wUser.Name;
            }

            WMSPickDemand wWMSPickDemand = new WMSPickDemand(0, "1900",
                    String.valueOf(WMSOrderType.OutLL.getValue()), wCode, expectTime1, expectTime2, monitorNo,
                    monitor, wList.get(0).ProductID, APSConstans.GetFPCProductNo(wList.get(0).ProductID),
                    wList.get(0).LineID, APSConstans.GetFMCLineName(wList.get(0).LineID), wList.get(0).CustomerID,
                    APSConstans.GetCRMCustomer(wList.get(0).CustomerID).CustomerName,
                    APSConstans.GetCRMCustomer(wList.get(0).CustomerID).CustomerCode, wList.get(0).OrderID,
                    wList.get(0).PartNo, wList.get(0).PartID, APSConstans.GetFPCPartName(wList.get(0).PartID),
                    APSConstans.GetFPCPart(wList.get(0).PartID).Code, "", "", wBaseTime, "", "", wBaseTime, 1,
                    wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(), wList.get(0).WBSNo, wBaseTime);
            wWMSPickDemand.SourceID = wOutPickDemand.ID;
            wWMSPickDemand.SourceCode = wOutPickDemand.DemandNo;
            wWMSPickDemand.SourceType = WMSPickDemandSourceType.OutSourceReapir.getValue();
            int wDemandID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wWMSPickDemand, wErrorCode);
            if (wDemandID <= 0) {
                return;
            }
            // ④创建领料需求单明细
            int wIndex = 1;

            for (IPTOutsourcingMaterial wMRPMaterialPlan : wList) {
                double wFQTY = wMRPMaterialPlan.FQTY;
                // 获取配套属性
                String wGroup = "";
                if (wFQTY > 0) {
                    WMSPickDemandItem wWMSPickDemandItem = new WMSPickDemandItem(0, wDemandID,
                            wMRPMaterialPlan.MaterialID, wMRPMaterialPlan.MaterialNo, wMRPMaterialPlan.MaterialName,
                            wFQTY, wOMSOrder.OrderNo, wMRPMaterialPlan.StepID,
                            APSConstans.GetFPCPartPoint(wMRPMaterialPlan.StepID).Code.replace("PS-", ""),
                            APSConstans.GetFPCPartPointName(wMRPMaterialPlan.StepID), String.valueOf(wIndex), wGroup,
                            0,
                            "",
                            wMRPMaterialPlan.OutSourceType,
                            SFCOutSourceType.getEnumType(wMRPMaterialPlan.OutSourceType).getLable(),
                            "修复旧件", "", wBaseTime, wWMSPickDemand.PartID,
                            0, wMRPMaterialPlan.FQTY, 0);

//                    wWMSPickDemandItem.IsOriDis=wAPSBOMItem.OriginalType==1?"是":"否";

                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem, wErrorCode);
                    wIndex++;
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    @Override
    public ServiceResult<Integer> WMS_MPSDisassembly(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);

            List<WMSSubRepairReceipt> wHeaderList = new ArrayList<>();
            WMSSubRepairReceipt wWMSSubRepairReceipt = GetWMSSubRepairReceipt(wPickDemand);
            wHeaderList.add(wWMSSubRepairReceipt);
            WMSSubRepairReceipts wWMSSubRepairReceipts = new WMSSubRepairReceipts(wHeaderList);
            WMSReturn wReturn = MyHelperServiceImpl.getInstance().WMS_MPSDisassembly(wWMSSubRepairReceipts,
                    wPickDemand);
            if (wReturn.returnFlag.equals("1")) {
                wPickDemand.Status = WMSPickDemandStatusNew.PendingHandover.getValue();
                wPickDemand.SendStatus = 1;
                wPickDemand.SendDesc = "推送成功";
                // 发送待办消息给申请人进行委外拆修入库交接
                List<BFCMessage> wBFCMessageList = new ArrayList<>();
                BFCMessage wMessage = null;
                SimpleDateFormat wSDF = new SimpleDateFormat("yyyyMMdd");
                int wShiftID = Integer.parseInt(wSDF.format(Calendar.getInstance().getTime()));

                List<Integer> wUserIDList = new ArrayList<>(Collections.singletonList(wPickDemand.CreateID));
                String wMessageText = StringUtils.Format("【{0}】-【{2}】-【{3}】 {1}已发起委外拆修入库申请，请及时完成入库交接。",
                        BPMEventModule.OutRepairInStockHanover.getLable(), wLoginUser.Name, wPickDemand.PartNo,
                        wPickDemand.PartName);

                for (int wUserID : wUserIDList) {
                    // 发送任务消息到人员
                    wMessage = new BFCMessage();
                    wMessage.Active = 0;
                    wMessage.CompanyID = 0;
                    wMessage.CreateTime = Calendar.getInstance();
                    wMessage.EditTime = Calendar.getInstance();
                    wMessage.ID = 0;
                    wMessage.MessageID = wPickDemand.ID;
                    wMessage.Title = wPickDemand.DemandNo;
                    wMessage.MessageText = wMessageText;
                    wMessage.ModuleID = BPMEventModule.OutRepairInStockHanover.getValue();
                    wMessage.ResponsorID = wUserID;
                    wMessage.ShiftID = wShiftID;
                    wMessage.StationID = 0;
                    wMessage.Type = BFCMessageType.Task.getValue();
                    wBFCMessageList.add(wMessage);
                }

                CoreServiceImpl.getInstance().BFC_UpdateMessageList(BaseDAO.SysAdmin, wBFCMessageList);

                // 创建委外送修跟踪台账
                ExecutorService wES = Executors.newFixedThreadPool(1);
                wES.submit(() -> MyHelperServiceImpl.getInstance().CreateSFCOutMaterialTrackLedgerList(wLoginUser,
                        wPickDemand));
                wES.shutdown();
            } else {
                wPickDemand.SendStatus = 2;

                if (StringUtils.isEmpty(wReturn.returnDesc))
                    wPickDemand.SendDesc = "网络错误";
                else
                    wPickDemand.SendDesc = wReturn.returnDesc;

                wResult.FaultCode += wReturn.returnDesc;
            }

            WMSPickDemandDAO.getInstance().Update(wLoginUser, wPickDemand, wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取待推送的委外拆修入库数据
     */
    private WMSSubRepairReceipt GetWMSSubRepairReceipt(WMSPickDemand wPickDemand) {
        WMSSubRepairReceipt wResult = new WMSSubRepairReceipt();
        try {
            wResult.warehouseId = "WH01";
            wResult.customerId = "1900";
            wResult.asnType = "200";
            wResult.docNo = wPickDemand.DemandNo;
            wResult.expectedArriveTime1 = wPickDemand.ExpectTime1Text;
            wResult.expectedArriveTime2 = wPickDemand.ExpectTime2Text;
            wResult.supplierId = wPickDemand.MonitorNo;
            wResult.supplierName = wPickDemand.Monitor;
            wResult.hedi01 = wPickDemand.ProductNo;
            wResult.hedi02 = wPickDemand.LineName;
            wResult.hedi03 = wPickDemand.CustomerCode;
            wResult.hedi04 = wPickDemand.PartNo.contains("#") ? wPickDemand.PartNo.split("#")[1] : wPickDemand.PartNo;
            wResult.hedi05 = wPickDemand.PartName;
            wResult.hedi06 = wPickDemand.PartCode;
            wResult.hedi07 = wPickDemand.WBSNo;
            wResult.details = new ArrayList<>();

            SimpleDateFormat wSDF = new SimpleDateFormat("yyyy-MM-dd");
            for (WMSPickDemandItem wItem : wPickDemand.ItemList) {
                WMSSubRepairReceiptDetail wWMSSubRepairReceiptDetail = new WMSSubRepairReceiptDetail();
                wWMSSubRepairReceiptDetail.sku = wItem.MaterialNo;
                wWMSSubRepairReceiptDetail.expectedQty = String.valueOf(wItem.FQTY);
                wWMSSubRepairReceiptDetail.lotAtt01 = wSDF.format(wItem.ProductTime.getTime());
                wWMSSubRepairReceiptDetail.lotAtt02 = wSDF.format(Calendar.getInstance().getTime());
                wWMSSubRepairReceiptDetail.lotAtt03 = wSDF.format(Calendar.getInstance().getTime());
                wWMSSubRepairReceiptDetail.lotAtt04 = "1200";
                wWMSSubRepairReceiptDetail.lotAtt05 = "";
                wWMSSubRepairReceiptDetail.lotAtt07 = wItem.ProductName;
                // wWMSSubRepairReceiptDetail.lotAtt08 = wItem.WBSNo.substring(0, 9);
                wWMSSubRepairReceiptDetail.lotAtt08 = wItem.WBSNo;
                wWMSSubRepairReceiptDetail.lotAtt09 = wItem.BatchNumber;
                wWMSSubRepairReceiptDetail.lotAtt10 = wItem.SerialNo;
                wWMSSubRepairReceiptDetail.lotAtt11 = StringUtils.isEmpty(wItem.AssessmentType) ? "修复旧件"
                        : wItem.AssessmentType;
                wWMSSubRepairReceiptDetail.dedi01 = wItem.PartPointCode;
                wWMSSubRepairReceiptDetail.dedi02 = wItem.PartPointName;
                wWMSSubRepairReceiptDetail.dedi03 = wItem.RowNo;
                wWMSSubRepairReceiptDetail.dedi04 = wItem.IsOriDis;

                wResult.details.add(wWMSSubRepairReceiptDetail);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_CopyPickDemand(BMSEmployee wLoginUser, int wID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wID, wErrorCode);
            if (wPickDemand == null || wPickDemand.ID <= 0) {
                wResult.FaultCode += "提示：配送单不存在!";
                return wResult;
            }

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            wPickDemand.ID = 0;
            wPickDemand.WMSDemandNo = "";
            wPickDemand.DeliveryID = 0;
            wPickDemand.DeliveryMan = "";
            wPickDemand.DeliveryNo = "";
            wPickDemand.DeliveryTime = wBaseTime;
            wPickDemand.SorterID = 0;
            wPickDemand.Sorter = "";
            wPickDemand.SorterNo = "";
            wPickDemand.SorterTime = wBaseTime;
            wPickDemand.ReceiveID = 0;
            wPickDemand.ReceiveMan = "";
            wPickDemand.ReceiveNo = "";
            wPickDemand.ReceiveTime = wBaseTime;
            wPickDemand.ShortageIdentification = 0;
            wPickDemand.OriginalOrderNo = "";
            wPickDemand.SendStatus = 0;
            wPickDemand.SendDesc = "";
            wPickDemand.Status = WMSPickDemandStatus.Saved.getValue();
            wPickDemand.CreateTime = Calendar.getInstance();
            wPickDemand.WaveNumber = "";
            wPickDemand.DemandNo = WMSPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);

            int wNewID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wPickDemand, wErrorCode);
            if (wNewID > 0) {
                List<WMSPickDemandItem> wItemList = WMSPickDemandItemDAO.getInstance().SelectList(wLoginUser, -1, wID,
                        -1, "", -1, wErrorCode);
                for (WMSPickDemandItem wWMSPickDemandItem : wItemList) {
                    wWMSPickDemandItem.ID = 0;
                    wWMSPickDemandItem.DemandID = wNewID;
                    wWMSPickDemandItem.Status = 0;
                    wWMSPickDemandItem.PickedNumber = 0;
                    wWMSPickDemandItem.IsConfirmed = 0;
                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem, wErrorCode);
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_CancelDistribution(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);
            OMSOrder wOMSOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wDemand.OrderID, wErrorCode);

            boolean wIsActiveRowHandOver = Configuration.readConfigString("IsActiveRowHandOver", "config/config")
                    .equals("1");

            WMSReturn wReturn = MyHelperServiceImpl.getInstance().WMS_PostLLCancel(wDemand);
            if (wReturn.returnFlag.equals("1")) {
                wDemand.SendStatus = 1;
                wDemand.SendDesc = "取消成功";
                wDemand.Status = WMSPickDemandStatus.Canceled.getValue();

                if (wIsActiveRowHandOver) {
                    wDemand.Status = WMSPickDemandStatusNew.Canceld.getValue();
                }

                if (wOMSOrder.Status >= 5) {
                    wDemand.Remark = "完工车取消";
                    wDemand.IsFinish = 1;
                }

                WMSPickDemandDAO.getInstance().Update(wLoginUser, wDemand, wErrorCode);

                // 增加取消下发成功的操作日志
                LFSOperationLog wLFSOperationLog = new LFSOperationLog(0, wDemandID,
                        LFSOperationLogType.PickDemandCancel.getValue(),
                        LFSOperationLogType.PickDemandCancel.getLable(),
                        wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(),
                        StringUtils.Format("取消下发配送单【{0}】成功", wDemand.DemandNo));
                LFSServiceImpl.getInstance().LFS_UpdateOperationLog(wLoginUser, wLFSOperationLog);
            } else {
                wDemand.SendStatus = 2;
                wDemand.SendDesc = "仓库已开始作业，不符合取消条件";
                WMSPickDemandDAO.getInstance().Update(wLoginUser, wDemand, wErrorCode);

                // 增加取消下发失败的操作日志
                LFSOperationLog wLFSOperationLog = new LFSOperationLog(0, wDemandID,
                        LFSOperationLogType.PickDemandCancel.getValue(),
                        LFSOperationLogType.PickDemandCancel.getLable(),
                        wLoginUser.ID, wLoginUser.Name, Calendar.getInstance(),
                        StringUtils.Format("取消下发配送单【{0}】失败，仓库已开始作业，不符合取消条件。", wDemand.DemandNo));
                LFSServiceImpl.getInstance().LFS_UpdateOperationLog(wLoginUser, wLFSOperationLog);

                wResult.FaultCode += "仓库已开始作业，不符合取消条件";
                return wResult;
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<BPMTaskBase>> WMS_QueryMaterialReturnEmployeeAll(BMSEmployee wLoginUser, int wTagTypes,
                                                                               Calendar wStartTime, Calendar wEndTime) {
        ServiceResult<List<BPMTaskBase>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            switch (TagTypes.getEnumType(wTagTypes)) {
                case Applicant:// 2发起
                    wResult.Result = MESMaterialReturnDAO.getInstance().BPM_GetSendTaskList(wLoginUser, wLoginUser.ID,
                            wStartTime, wEndTime, wErrorCode);
                    for (BPMTaskBase wMTCTask : wResult.Result) {
                        wMTCTask.TagTypes = TaskQueryType.Sended.getValue();
                    }
                    break;
                case Dispatcher:// 1待做
                    wResult.Result = MESMaterialReturnDAO.getInstance().BPM_GetUndoTaskList(wLoginUser, wLoginUser.ID,
                            wErrorCode);
                    for (BPMTaskBase wMTCTask : wResult.Result) {
                        wMTCTask.TagTypes = TaskQueryType.ToHandle.getValue();
                    }
                    break;
                case Approver:// 4已做
                    wResult.Result = MESMaterialReturnDAO.getInstance().BPM_GetDoneTaskList(wLoginUser, wLoginUser.ID,
                            wStartTime, wEndTime, wErrorCode);
                    for (BPMTaskBase wMTCTask : wResult.Result) {
                        wMTCTask.TagTypes = TaskQueryType.Handled.getValue();
                    }
                    break;
                default:
                    break;
            }

            if (wResult.Result.size() > 0) {
                wResult.Result = wResult.Result.stream().filter(p -> p.Status != 0).collect(Collectors.toList());
            }

            // 排序
            wResult.Result.sort(Comparator.comparing(BPMTaskBase::getCreateTime, Comparator.reverseOrder()));

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateMaterialReturn(BMSEmployee wLoginUser,
                                                           MESMaterialReturn wMESMaterialReturn) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            MESMaterialReturn wUpdateItem = MESMaterialReturnDAO.getInstance().Update(wLoginUser, wMESMaterialReturn,
                    wErrorCode);
            wResult.Result = wUpdateItem.ID;

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_ShowReturnQRCode(BMSEmployee wLoginUser, int wReturnTaskID) {
        ServiceResult<String> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            MESMaterialReturn wItem = MESMaterialReturnDAO.getInstance().SelectByID(wLoginUser, wReturnTaskID,
                    wErrorCode);

            SimpleDateFormat wSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String wCurrentTime = wSDF.format(Calendar.getInstance().getTime());
            // ①存放在二维码中的内容
            String text = StringUtils.Format("{0},{1},{2}", wItem.Code, wLoginUser.LoginID, wCurrentTime);

            // ②嵌入二维码的图片路径
            String imgPath = "";
            // ③文件名称
            String wFileName = UUID.randomUUID().toString().replaceAll("-", "");
            // ④生成的二维码的路径及名称
            String wDirePath = StringUtils.Format("{0}static/export/{1}.jpg",
                    Constants.getConfigPath().replace("config/", ""), wFileName);
            File wDirFile = new File(wDirePath);
            if (!wDirFile.exists()) {
                wDirFile.mkdirs();
            }
            // ⑥生成二维码
            QRCodeUtil.encode(text, imgPath, wDirePath, true);
            // ⑦返回路径
            wResult.Result = StringUtils.Format("/{0}/export/{1}.jpg",
                    Configuration.readConfigString("project.name", "application"), wFileName);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_CodeScanningHandover(BMSEmployee wLoginUser, String wCode) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (StringUtils.isEmpty(wCode)) {
                return wResult;
            }

            MESMaterialReturn wMESMaterialReturn = (MESMaterialReturn) MESMaterialReturnDAO.getInstance()
                    .BPM_GetTaskInfo(wLoginUser, -1, wCode,
                            wErrorCode);
            if (wMESMaterialReturn == null || wMESMaterialReturn.ID <= 0) {
                return wResult;
            }
            wMESMaterialReturn.Status = MESMaterialReturnStatus.Handover.getValue();
            wMESMaterialReturn.StatusText = MESMaterialReturnStatus.Handover.getLable();
            MESMaterialReturnDAO.getInstance().BPM_UpdateTask(wLoginUser, wMESMaterialReturn, wErrorCode);

            // 关闭消息
            CoreServiceImpl.getInstance().BFC_MsgHandleTask(BaseDAO.SysAdmin,
                    BPMEventModule.MaterialReturnHandover.getValue(), 0,
                    3, new ArrayList<>(Collections.singletonList(wMESMaterialReturn.ID)), wMESMaterialReturn.UpFlowID,
                    1);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ManualPushMaterialReturn(BMSEmployee wLoginUser, int wReturnID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            MESMaterialReturn wData = (MESMaterialReturn) MESMaterialReturnDAO.getInstance().BPM_GetTaskInfo(wLoginUser,
                    wReturnID, "",
                    wErrorCode);

            List<MESMaterialReturnItem> wItemList = MESMaterialReturnItemDAO.getInstance().SelectList(wLoginUser,
                    -1, wData.ID, -1, -1, "", wErrorCode);
            OMSOrder wOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wData.OrderID, wErrorCode);
            WMSLinePartTLs wWMSLinePartTLs = MESMaterialReturnDAO.getInstance().GetWMSLinePartTLs(wData, wItemList);
            WMSReturn wReturn = MyHelperServiceImpl.getInstance().WMS_PostTL(wWMSLinePartTLs, wData, wOrder);
            if (wReturn.returnFlag.equals("1")) {
                wData.StatusText = "待退料交接";
                wData.SendStatus = 1;
                wData.SendDesc = "推送成功";

                // 发送待办消息给申请人，执行退料交接
                List<BFCMessage> wBFCMessageList = new ArrayList<>();
                BFCMessage wMessage = null;
                SimpleDateFormat wSDF = new SimpleDateFormat("yyyyMMdd");
                int wShiftID = Integer.parseInt(wSDF.format(Calendar.getInstance().getTime()));

                List<Integer> wUserIDList = new ArrayList<>(Collections.singletonList(wData.UpFlowID));
                String wMessageText = StringUtils.Format("【{0}】-【{2}】-【{3}】 {1}已审批，请及时与库房进行退料交接。",
                        BPMEventModule.MaterialReturnHandover.getLable(), wLoginUser.Name, wData.PartNo,
                        wData.PartName);

                for (int wUserID : wUserIDList) {
                    // 发送任务消息到人员
                    wMessage = new BFCMessage();
                    wMessage.Active = 0;
                    wMessage.CompanyID = 0;
                    wMessage.CreateTime = Calendar.getInstance();
                    wMessage.EditTime = Calendar.getInstance();
                    wMessage.ID = 0;
                    wMessage.MessageID = wData.ID;
                    wMessage.Title = wData.Code;
                    wMessage.MessageText = wMessageText;
                    wMessage.ModuleID = BPMEventModule.MaterialReturnHandover.getValue();
                    wMessage.ResponsorID = wUserID;
                    wMessage.ShiftID = wShiftID;
                    wMessage.StationID = 0;
                    wMessage.Type = BFCMessageType.Task.getValue();
                    wBFCMessageList.add(wMessage);
                }

                CoreServiceImpl.getInstance().BFC_UpdateMessageList(BaseDAO.SysAdmin, wBFCMessageList);
            } else {
                wData.StatusText = "申请退料失败";
                wData.SendStatus = 2;
                wData.SendDesc = wReturn.returnDesc;
            }

            MESMaterialReturnDAO.getInstance().BPM_UpdateTask(wLoginUser, wData,
                    wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_LineInventoryCount(BMSEmployee wLoginUser, int wLineEdgeID,
                                                         double wFQTY) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSLineEdgeLibrary wWMSLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                    wLineEdgeID, wErrorCode);
            if (wWMSLineEdgeLibrary == null || wWMSLineEdgeLibrary.ID <= 0) {
                return wResult;
            }
            double wOldFQTY = wWMSLineEdgeLibrary.FQTY;

            if (wOldFQTY == wFQTY) {
                return wResult;
            }

            wWMSLineEdgeLibrary.FQTY = wFQTY;
            wWMSLineEdgeLibrary.EditTime = Calendar.getInstance();
            WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);

            int wType = 0;
            if (wOldFQTY < wFQTY) {
                wType = WMSInventoryCheckType.InventorySurplus.getValue();
            } else {
                wType = WMSInventoryCheckType.InventoryLoss.getValue();
            }
            WMSInventoryCheck wWMSInventoryCheck = new WMSInventoryCheck(0, wLineEdgeID, wWMSLineEdgeLibrary.MaterialID,
                    wLoginUser.ID, Calendar.getInstance(), wOldFQTY, wFQTY, wType, 1);
            WMSInventoryCheckDAO.getInstance().Update(wLoginUser, wWMSInventoryCheck, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSInventoryCheck>> WMS_QueryLineInventoryList(BMSEmployee wLoginUser, int wLineEdgeID) {
        ServiceResult<List<WMSInventoryCheck>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSLineEdgeLibrary wWMSLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                    wLineEdgeID, wErrorCode);
            if (wWMSLineEdgeLibrary == null || wWMSLineEdgeLibrary.ID <= 0) {
                return wResult;
            }

            wResult.Result = WMSInventoryCheckDAO.getInstance().SelectList(wLoginUser, -1, wLineEdgeID, -1, -1, 1,
                    wErrorCode);
            wResult.Result.forEach(p -> {
                p.UnitText = wWMSLineEdgeLibrary.UnitText;
                p.MinPacking = wWMSLineEdgeLibrary.MinPacking;
                p.BatchNumber = wWMSLineEdgeLibrary.BatchNumber;
                p.Stock = wWMSLineEdgeLibrary.Stock;
                p.Supplier = wWMSLineEdgeLibrary.Supplier;
                p.ProductName = wWMSLineEdgeLibrary.ProductName;
                p.SerialNo = wWMSLineEdgeLibrary.SerialNo;
                p.ProductTime = wWMSLineEdgeLibrary.ProductTime;
                p.MaterialNo = wWMSLineEdgeLibrary.MaterialNo;
                p.MaterialName = wWMSLineEdgeLibrary.MaterialName;
            });

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_ExportPrintFile(BMSEmployee wLoginUser, int wReturnID) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wReturnID <= 0) {
                return wResult;
            }

            MESMaterialReturn wMESMaterialReturn = MESMaterialReturnDAO.getInstance().SelectByID(wLoginUser, wReturnID,
                    wErrorCode);

            List<MESMaterialReturnItem> wItemList = MESMaterialReturnItemDAO.getInstance().SelectList(wLoginUser, -1,
                    wReturnID, -1, -1, "",
                    wErrorCode);

            MyExcelSheet wMyExcelSheet = MESMaterialReturnDAO.getInstance().GetMyExcelSheet(wMESMaterialReturn,
                    wItemList);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<>(Collections.singletonList(wMyExcelSheet));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, "退料清单");

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSAreaStock> WMS_QueryAreaStock(BMSEmployee wLoginUser, int wID) {
        ServiceResult<WMSAreaStock> wResult = new ServiceResult<>();
        wResult.Result = new WMSAreaStock();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSAreaStockDAO.getInstance().SelectByID(wLoginUser, wID, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateAreaStock(BMSEmployee wLoginUser, WMSAreaStock wWMSAreaStock) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSAreaStockDAO.getInstance().Update(wLoginUser, wWMSAreaStock, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSAreaStock>> WMS_QueryAreaStockList(BMSEmployee wLoginUser, int wAreaID,
                                                                    String wMaterial, String wBatchNumber,
                                                                    String wSerialNo, Calendar wStartTime,
                                                                    Calendar wEndTime) {
        ServiceResult<List<WMSAreaStock>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSAreaStockDAO.getInstance().SelectList(wLoginUser, -1, wAreaID, wBatchNumber,
                    -1, wSerialNo, wMaterial, wStartTime, wEndTime, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<WMSBatchPickDemand> WMS_QueryBatchPickDemand(BMSEmployee wLoginUser, int wID) {
        ServiceResult<WMSBatchPickDemand> wResult = new ServiceResult<>();
        wResult.Result = new WMSBatchPickDemand();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSBatchPickDemandDAO.getInstance().SelectByID(wLoginUser, wID, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSBatchPickDemand>> WMS_QueryBatchPickDemandList(BMSEmployee wLoginUser,
                                                                                String wDemandNo, int wProductID,
                                                                                int wLineID, int wStatus,
                                                                                String wWMSDemandNo,
                                                                                String wSourceCode,
                                                                                int wShortageIdentification,
                                                                                String wOriginalOrderNo,
                                                                                Calendar wStartTime,
                                                                                Calendar wEndTime) {
        ServiceResult<List<WMSBatchPickDemand>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSBatchPickDemandDAO.getInstance().SelectList(wLoginUser, -1, wDemandNo, wProductID,
                    wLineID, wStatus, wWMSDemandNo, wSourceCode, wShortageIdentification, wOriginalOrderNo, wStartTime,
                    wEndTime, wErrorCode);
            // 排序
            wResult.Result.sort(Comparator.comparing(WMSBatchPickDemand::getCreateTime, Comparator.reverseOrder()));

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateBatchPickDemand(BMSEmployee wLoginUser,
                                                            WMSBatchPickDemand wWMSBatchPickDemand) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSBatchPickDemandDAO.getInstance().Update(wLoginUser, wWMSBatchPickDemand, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ManualPushatchPickDemand(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSBatchPickDemand wBatchPickDemand = WMSBatchPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID,
                    wErrorCode);

            List<WMSLinePartLL> wHeaderList = new ArrayList<>();
            WMSLinePartLL wWMSLinePartLL = GetWMSLinePartLL(wBatchPickDemand);
            wHeaderList.add(wWMSLinePartLL);
            WMSLinePartLLs wWMSLinePartLLs = new WMSLinePartLLs(wHeaderList);
            WMSReturn wReturn = MyHelperServiceImpl.getInstance().WMS_PostLL(wWMSLinePartLLs, wBatchPickDemand);
            if (wReturn.returnFlag.equals("1")) {
                wBatchPickDemand.Status = WMSPickDemandStatus.Sended.getValue();
                wBatchPickDemand.SendStatus = 1;
                wBatchPickDemand.SendDesc = "推送成功";
            } else {
                wBatchPickDemand.SendStatus = 2;

                if (StringUtils.isEmpty(wReturn.returnDesc))
                    wBatchPickDemand.SendDesc = "网络错误";
                else
                    wBatchPickDemand.SendDesc = wReturn.returnDesc;

                wResult.FaultCode += wReturn.returnDesc;
            }

            WMSBatchPickDemandDAO.getInstance().Update(wLoginUser, wBatchPickDemand, wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_ShowQRCodeBatchPickDemand(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<String> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSBatchPickDemand wItem = WMSBatchPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID,
                    wErrorCode);

            SimpleDateFormat wSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String wCurrentTime = wSDF.format(Calendar.getInstance().getTime());
            // ①存放在二维码中的内容
            String text = "";
            if (wItem.Status == WMSPickDemandStatus.Picked.getValue()
                    || wItem.Status == WMSPickDemandStatus.Sended.getValue()) {
                text = StringUtils.Format("{0},{1},{2}", wItem.DemandNo, wLoginUser.LoginID, wCurrentTime);

                wItem.DeliveryID = wLoginUser.ID;
                WMSBatchPickDemandDAO.getInstance().Update(wLoginUser, wItem, wErrorCode);

            } else {
                wResult.FaultCode += "提示：状态错误!";
                return wResult;
            }

            // ②嵌入二维码的图片路径
            String imgPath = "";
            // ③文件名称
            String wFileName = UUID.randomUUID().toString().replaceAll("-", "");
            // ④生成的二维码的路径及名称
            String wDirePath = StringUtils.Format("{0}static/export/{1}.jpg",
                    Constants.getConfigPath().replace("config/", ""), wFileName);
            File wDirFile = new File(wDirePath);
            if (!wDirFile.exists()) {
                wDirFile.mkdirs();
            }
            // ⑥生成二维码
            QRCodeUtil.encode(text, imgPath, wDirePath, true);
            // ⑦返回路径
            wResult.Result = StringUtils.Format("/{0}/export/{1}.jpg",
                    Configuration.readConfigString("project.name", "application"), wFileName);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_CancelDistributionBatchPickDemand(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSBatchPickDemand wDemand = WMSBatchPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID,
                    wErrorCode);

            WMSReturn wReturn = MyHelperServiceImpl.getInstance().WMS_PostLLCancel(wDemand);
            if (wReturn.returnFlag.equals("1")) {
                wDemand.SendStatus = 1;
                wDemand.SendDesc = "取消成功";
                wDemand.Status = WMSPickDemandStatus.Canceled.getValue();
                WMSBatchPickDemandDAO.getInstance().Update(wLoginUser, wDemand, wErrorCode);
            } else {
                wDemand.SendStatus = 2;
                wDemand.SendDesc = "仓库已开始作业，不符合取消条件";
                WMSBatchPickDemandDAO.getInstance().Update(wLoginUser, wDemand, wErrorCode);
                wResult.FaultCode += "仓库已开始作业，不符合取消条件";
                return wResult;
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateBatchPickDemandItem(BMSEmployee wLoginUser,
                                                                WMSBatchPickDemandItem wWMSBatchPickDemandItem) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSBatchPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSBatchPickDemandItem,
                    wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_IncomingLineSideLibrary(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSBatchPickDemand wWMSBatchPickDemand = WMSBatchPickDemandDAO.getInstance().SelectByID(wLoginUser,
                    wDemandID, wErrorCode);
            if (wWMSBatchPickDemand == null || wWMSBatchPickDemand.ID <= 0 || wWMSBatchPickDemand.ItemList == null
                    || wWMSBatchPickDemand.ItemList.size() <= 0) {
                return wResult;
            }

            SFCBatchBOMTaskBPM wSFCBatchBOMTaskBPM = SFCBatchBOMTaskBPMDAO.getInstance().SelectByID(wLoginUser,
                    wWMSBatchPickDemand.SourceID, wErrorCode);
            if (wSFCBatchBOMTaskBPM == null || wSFCBatchBOMTaskBPM.ID <= 0
                    || wSFCBatchBOMTaskBPM.SFCBatchBOMTaskBPMItemList == null
                    || wSFCBatchBOMTaskBPM.SFCBatchBOMTaskBPMItemList.size() <= 0) {
                return wResult;
            }

            List<SFCBatchBOMTaskBPMItem> wItemList = wSFCBatchBOMTaskBPM.SFCBatchBOMTaskBPMItemList;

            // 获取工区工位字典
            Map<Integer, Integer> wPartAreaMap = WMSBatchPickDemandDAO.getInstance().GetPartAreaMap(wLoginUser,
                    wErrorCode);
            // 物料分工区进行分配
            List<WMSBatchPickDemandItem> wWMSBatchPickDemandItemList = wWMSBatchPickDemand.ItemList.stream()
                    .filter(p -> p.PickedNumber > 0).collect(Collectors.toList());

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);
            for (WMSBatchPickDemandItem wWMSBatchPickDemandItem : wWMSBatchPickDemandItemList) {
                // 分批次入线边库
                this.InstockByBatchNumber(wLoginUser, wWMSBatchPickDemandItem, wItemList, wPartAreaMap, wErrorCode);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 分批次入线边库
     */
    private void InstockByBatchNumber(BMSEmployee wLoginUser, WMSBatchPickDemandItem wWMSBatchPickDemandItem,
                                      List<SFCBatchBOMTaskBPMItem> wItemList, Map<Integer, Integer> wPartAreaMap,
                                      OutResult<Integer> wErrorCode) {
        try {
            if (wItemList == null || wItemList.size() <= 0) {
                return;
            }

            if (!wPartAreaMap.containsKey(wItemList.get(0).PartID)) {
                return;
            }

            int wAreaID = wPartAreaMap.get(wItemList.get(0).PartID);
            if (wAreaID <= 0) {
                return;
            }

            List<WMSBatchPickDemandItemStock> wItemStockList = WMSBatchPickDemandItemStockDAO.getInstance().SelectList(
                    wLoginUser, -1,
                    wWMSBatchPickDemandItem.ID, "",
                    "", wErrorCode);
            if (wItemStockList == null || wItemStockList.size() <= 0) {
                return;
            }

            for (WMSBatchPickDemandItemStock wWMSBatchPickDemandItemStock : wItemStockList) {
                WMSLineEdgeLibrary wWMSLineEdgeLibrary = new WMSLineEdgeLibrary(0,
                        wWMSBatchPickDemandItem.MaterialID,
                        wWMSBatchPickDemandItem.MaterialName, wWMSBatchPickDemandItem.MaterialNo, 0,
                        APSConstans.GetCFGUnit(wWMSBatchPickDemandItem.UnitText).ID, "", 0, Calendar.getInstance(), "",
                        Calendar.getInstance(), "",
                        0, wWMSBatchPickDemandItemStock.BatchNumber, wWMSBatchPickDemandItem.Stock,
                        wWMSBatchPickDemandItem.Supplier, wWMSBatchPickDemandItem.ProductName,
                        wWMSBatchPickDemandItem.SerialNo,
                        wWMSBatchPickDemandItem.ProductTime);
                wWMSLineEdgeLibrary.AreaID = wAreaID;
                wWMSLineEdgeLibrary.SourceType = 2;
                wWMSLineEdgeLibrary.FQTY = wWMSBatchPickDemandItemStock.PickedNumber;
                wWMSLineEdgeLibrary.Total = wWMSLineEdgeLibrary.FQTY;
                wWMSLineEdgeLibrary.BOMNumber = wWMSBatchPickDemandItem.BOMNumber;
                wWMSLineEdgeLibrary.ProjectStockNo = wWMSBatchPickDemandItemStock.ProjectStockNo;
                if (StringUtils.isEmpty(wWMSLineEdgeLibrary.SourceIDs)) {
                    wWMSLineEdgeLibrary.SourceIDs = String.valueOf(wWMSBatchPickDemandItem.DemandID);
                } else {
                    wWMSLineEdgeLibrary.SourceIDs = wWMSLineEdgeLibrary.SourceIDs + ","
                            + wWMSBatchPickDemandItem.DemandID;
                }
                List<WMSLineEdgeLibrary> wmsLineEdgeLibraries = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                        wLoginUser, -1,
                        wWMSLineEdgeLibrary.MaterialID, "",
                        null, null, wWMSLineEdgeLibrary.AreaID, 2, wWMSBatchPickDemandItemStock.BatchNumber,
                        wErrorCode);
                if (wmsLineEdgeLibraries.size() > 0) {
                    wmsLineEdgeLibraries.get(0).FQTY += wWMSLineEdgeLibrary.FQTY;
                    wmsLineEdgeLibraries.get(0).Total += wWMSLineEdgeLibrary.FQTY;

                    if (StringUtils.isEmpty(wmsLineEdgeLibraries.get(0).SourceIDs)) {
                        wmsLineEdgeLibraries.get(0).SourceIDs = String.valueOf(wWMSBatchPickDemandItem.DemandID);
                    } else {
                        wmsLineEdgeLibraries.get(0).SourceIDs = wmsLineEdgeLibraries.get(0).SourceIDs + ","
                                + wWMSBatchPickDemandItem.DemandID;
                    }

                    WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wmsLineEdgeLibraries.get(0),
                            wErrorCode);
                } else {
                    WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                }
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 指定批次入线边库
     */
    private void InstockByBatchNumber(BMSEmployee wLoginUser, WMSBatchPickDemandItem wWMSBatchPickDemandItem,
                                      List<SFCBatchBOMTaskBPMItem> wItemList, Map<Integer, Integer> wPartAreaMap,
                                      WMSBatchPickDemandItemStock wWMSBatchPickDemandItemStock,
                                      OutResult<Integer> wErrorCode) {
        try {
            if (wItemList == null || wItemList.size() <= 0) {
                return;
            }

            if (!wPartAreaMap.containsKey(wItemList.get(0).PartID)) {
                return;
            }

            int wAreaID = wPartAreaMap.get(wItemList.get(0).PartID);
            if (wAreaID <= 0) {
                return;
            }

            WMSLineEdgeLibrary wWMSLineEdgeLibrary = new WMSLineEdgeLibrary(0,
                    wWMSBatchPickDemandItem.MaterialID,
                    wWMSBatchPickDemandItem.MaterialName, wWMSBatchPickDemandItem.MaterialNo, 0,
                    APSConstans.GetCFGUnit(wWMSBatchPickDemandItem.UnitText).ID, "", 0, Calendar.getInstance(), "",
                    Calendar.getInstance(), "",
                    0, wWMSBatchPickDemandItemStock.BatchNumber, wWMSBatchPickDemandItem.Stock,
                    wWMSBatchPickDemandItem.Supplier, wWMSBatchPickDemandItem.ProductName,
                    wWMSBatchPickDemandItem.SerialNo,
                    wWMSBatchPickDemandItem.ProductTime);
            wWMSLineEdgeLibrary.AreaID = wAreaID;
            wWMSLineEdgeLibrary.SourceType = 2;
            wWMSLineEdgeLibrary.FQTY = wWMSBatchPickDemandItemStock.PickedNumber;
            wWMSLineEdgeLibrary.Total = wWMSLineEdgeLibrary.FQTY;
            wWMSLineEdgeLibrary.BOMNumber = wWMSBatchPickDemandItem.BOMNumber;
            wWMSLineEdgeLibrary.ProjectStockNo = wWMSBatchPickDemandItemStock.ProjectStockNo;
            if (StringUtils.isEmpty(wWMSLineEdgeLibrary.SourceIDs)) {
                wWMSLineEdgeLibrary.SourceIDs = String.valueOf(wWMSBatchPickDemandItem.DemandID);
            } else {
                wWMSLineEdgeLibrary.SourceIDs = wWMSLineEdgeLibrary.SourceIDs + ","
                        + wWMSBatchPickDemandItem.DemandID;
            }
            List<WMSLineEdgeLibrary> wmsLineEdgeLibraries = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                    wLoginUser, -1,
                    wWMSLineEdgeLibrary.MaterialID, "",
                    null, null, wWMSLineEdgeLibrary.AreaID, 2, wWMSBatchPickDemandItemStock.BatchNumber,
                    wErrorCode);
            if (wmsLineEdgeLibraries.size() > 0) {
                wmsLineEdgeLibraries.get(0).FQTY += wWMSLineEdgeLibrary.FQTY;
                wmsLineEdgeLibraries.get(0).Total += wWMSLineEdgeLibrary.FQTY;

                if (StringUtils.isEmpty(wmsLineEdgeLibraries.get(0).SourceIDs)) {
                    wmsLineEdgeLibraries.get(0).SourceIDs = String.valueOf(wWMSBatchPickDemandItem.DemandID);
                } else {
                    wmsLineEdgeLibraries.get(0).SourceIDs = wmsLineEdgeLibraries.get(0).SourceIDs + ","
                            + wWMSBatchPickDemandItem.DemandID;
                }

                WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wmsLineEdgeLibraries.get(0),
                        wErrorCode);
            } else {
                WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    private double GetTotalSize(Map<Integer, Double> wAreaNumberMap) {
        double wResult = 0.0;
        try {
            for (Integer wAreaID : wAreaNumberMap.keySet()) {
                wResult += wAreaNumberMap.get(wAreaID);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSBatchPickDemand>> WMS_QueryBatchPickDemandEmployeeAll(BMSEmployee wLoginUser,
                                                                                       int wTagType,
                                                                                       Calendar wStartTime,
                                                                                       Calendar wEndTime) {
        ServiceResult<List<WMSBatchPickDemand>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            switch (wTagType) {
                case 1:
                    List<Integer> wTaskIDList = BFCMessageDAO.getInstance().BFC_QueryMessageIDToDoList(wLoginUser,
                            BPMEventModule.BatchOccasionNCRSend.getValue(), wErrorCode);
                    if (wTaskIDList.size() > 0) {
                        wResult.Result = WMSBatchPickDemandDAO.getInstance().SelectListByIDList(wLoginUser,
                                wTaskIDList, wErrorCode);
                    }
                    break;
                case 2:
                    wResult.Result = WMSBatchPickDemandDAO.getInstance().SelectTaskDoneList(wLoginUser, wStartTime,
                            wEndTime,
                            wErrorCode);
                    break;
                default:
                    break;
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_QueryOutQRCode(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wItem = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);

            String wTextMain = wItem.DemandNo;
            String wQRCode = getQRCodeString(wLoginUser, wTextMain);

            Map<Integer, String> wMap = new HashMap<>();
            wResult.CustomResult.put("MainCode", wQRCode);
            for (WMSPickDemandItem wWMSPickDemandItem : wItem.ItemList) {
                String wText = wWMSPickDemandItem.MaterialNo;

                wText = StringUtils.Format("M{0}%Q{1}%U{2}%A{3}%B{4}%C{5}%D{6}%W{7}%N{8}%Z{9}",
                        wWMSPickDemandItem.MaterialNo, String.valueOf(wWMSPickDemandItem.FQTY),
                        wWMSPickDemandItem.UnitText, wWMSPickDemandItem.ProductNo, wWMSPickDemandItem.LineName,
                        wWMSPickDemandItem.CustomerName,
                        wWMSPickDemandItem.PartNo.split("#")[1], "", wWMSPickDemandItem.SerialNo,
                        "001");

                String wString = getQRCodeString(wLoginUser, wText);
                wMap.put(wWMSPickDemandItem.ID, wString);
            }
            wResult.CustomResult.put("SubCodes", wMap);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    private String getQRCodeString(BMSEmployee wLoginUser, String wText) {
        String wResult = "";
        try {
            // ②嵌入二维码的图片路径
            String imgPath = "";
            // ③文件名称
            String wFileName = UUID.randomUUID().toString().replaceAll("-", "");
            // ④生成的二维码的路径及名称
            String wDirePath = StringUtils.Format("{0}static/export/{1}.jpg",
                    Constants.getConfigPath().replace("config/", ""), wFileName);
            File wDirFile = new File(wDirePath);
            if (!wDirFile.exists()) {
                wDirFile.mkdirs();
            }
            // ⑥生成二维码
            QRCodeUtil.encode(wText, imgPath, wDirePath, true);
            // ⑦返回路径
            wResult = StringUtils.Format("/{0}/export/{1}.jpg",
                    Configuration.readConfigString("project.name", "application"), wFileName);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }

        return wResult;
    }

    @Override
    public ServiceResult<List<WMSPickDemandItemStock>> WMS_QueryPickDemandItemStockList(BMSEmployee wLoginUser,
                                                                                        int wTaskID,
                                                                                        String wBatchNumber,
                                                                                        String wSerialNo) {
        ServiceResult<List<WMSPickDemandItemStock>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSPickDemandItemStockDAO.getInstance().SelectList(wLoginUser, -1, wTaskID, wBatchNumber,
                    wSerialNo, wErrorCode);
            if (wTaskID > 0) {
                WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(wLoginUser,
                        wTaskID,
                        wErrorCode);
                wResult.CustomResult.put("Task", wWMSPickDemandItem);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSBatchPickDemandItemStock>> WMS_QueryBatchPickDemandItemStockList(
            BMSEmployee wLoginUser,
            int wTaskID,
            String wBatchNumber, String wSerialNo) {
        ServiceResult<List<WMSBatchPickDemandItemStock>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSBatchPickDemandItemStockDAO.getInstance().SelectList(wLoginUser, -1, wTaskID,
                    wBatchNumber, wSerialNo, wErrorCode);
            if (wTaskID > 0) {
                WMSBatchPickDemandItem wWMSPickDemandItem = WMSBatchPickDemandItemDAO.getInstance().SelectByID(
                        wLoginUser,
                        wTaskID,
                        wErrorCode);
                wResult.CustomResult.put("Task", wWMSPickDemandItem);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSLineEdgeLibrary>> WMS_BatchSourceList(BMSEmployee wLoginUser, int wPartID,
                                                                       int wSourceType, int wProductID, int wLineID) {
        ServiceResult<List<WMSLineEdgeLibrary>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSLineEdgeLibraryDAO.getInstance().WMS_QueryListByPartAndSourceType(wLoginUser, wPartID,
                    wSourceType, wErrorCode);

            // 扣减及时库存，已发起的单据
            List<SFCBOMTaskItem> wUsedList = WMSLineEdgeLibraryDAO.getInstance()
                    .WMS_QueryUsedBOMTaskItemList(wLoginUser, wErrorCode);
            for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wResult.Result) {
                List<SFCBOMTaskItem> wItemList = wUsedList.stream().filter(p -> p.BOMItemID == wWMSLineEdgeLibrary.ID)
                        .collect(Collectors.toList());
                for (SFCBOMTaskItem wSFCBOMTaskItem : wItemList) {
                    wWMSLineEdgeLibrary.FQTY -= wSFCBOMTaskItem.MaterialNumber;
                }
            }

            // 合并多批次物料
            List<WMSLineEdgeLibrary> wList = new ArrayList<>(wResult.Result.stream()
                    .collect(Collectors.toMap(WMSLineEdgeLibrary::getMaterialID, account -> account, (k1, k2) -> k2))
                    .values());
            for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wList) {
                double wFQTY = 0.0;
                List<WMSLineEdgeLibrary> wSameList = wResult.Result.stream()
                        .filter(p -> p.MaterialID == wWMSLineEdgeLibrary.MaterialID).collect(Collectors.toList());
                for (WMSLineEdgeLibrary wItem : wSameList) {
                    wFQTY += wItem.FQTY;
                }
                wWMSLineEdgeLibrary.FQTY = wFQTY;
            }
            wResult.Result = wList;

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_LineEdgeCovaUse(BMSEmployee wLoginUser,
                                                      List<SFCBOMTaskItem> wSFCBOMTaskItemList,
                                                      List<APSBOMItem> wAPSBOMItemList) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wSFCBOMTaskItemList == null || wSFCBOMTaskItemList.size() <= 0) {
                return wResult;
            }

            SFCBOMTask wSFCBOMTask = (SFCBOMTask) SFCBOMTaskDAO.getInstance().BPM_GetTaskInfo(wLoginUser,
                    wSFCBOMTaskItemList.get(0).SFCBOMTaskID, "", wErrorCode);
            if (wSFCBOMTask == null || wSFCBOMTask.ID <= 0) {
                return wResult;
            }

            List<ZIF_MM_GET_WMS281_WSStub.ZFMM_GET_WMS281Response> wGZList = new ArrayList<>();
            for (SFCBOMTaskItem wSFCBOMTaskItem : wSFCBOMTaskItemList) {
                WMSLineEdgeLibrary wWMSLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                        wSFCBOMTaskItem.BOMItemID, wErrorCode);
                if (wWMSLineEdgeLibrary == null || wWMSLineEdgeLibrary.ID <= 0) {
                    continue;
                }

                if (wAPSBOMItemList.stream().noneMatch(p -> p.PartID == wSFCBOMTask.PartID
                        && p.PartPointID == wSFCBOMTask.PartPointID && p.MaterialID == wSFCBOMTaskItem.MaterialID
                        && p.ReplaceType == wSFCBOMTaskItem.ReplaceType
                        && p.OutsourceType == wSFCBOMTaskItem.OutsourceType)) {
                    continue;
                }
                // 查询台车BOM
                APSBOMItem wAPSBOMItem = wAPSBOMItemList.stream().filter(p -> p.PartID == wSFCBOMTask.PartID
                        && p.PartPointID == wSFCBOMTask.PartPointID && p.MaterialID == wSFCBOMTaskItem.MaterialID
                        && p.ReplaceType == wSFCBOMTaskItem.ReplaceType
                        && p.OutsourceType == wSFCBOMTaskItem.OutsourceType).findFirst().get();
                // 消耗
                List<WMSLineEdgeLibrary> wLibraryList = WMSLineEdgeLibraryDAO.getInstance().SelectList(wLoginUser, -1,
                        wWMSLineEdgeLibrary.MaterialID, "",
                        null, null, -1, wWMSLineEdgeLibrary.SourceType, "", wErrorCode);
                // 排序
                wLibraryList.sort(Comparator.comparing(WMSLineEdgeLibrary::getBatchNumber));
                double wMaterialNumber = wSFCBOMTaskItem.MaterialNumber;
                for (WMSLineEdgeLibrary wItemLibrary : wLibraryList) {
                    if (wMaterialNumber <= 0) {
                        continue;
                    }

                    if (wItemLibrary.FQTY <= 0) {
                        continue;
                    }

                    if (wMaterialNumber > wItemLibrary.FQTY) {
                        double wCurrentFQTY = wItemLibrary.FQTY;
                        wItemLibrary.FQTY = 0;
                        wItemLibrary.EditTime = Calendar.getInstance();
                        WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wItemLibrary, wErrorCode);

                        WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem = new WMSLineEdgeLibraryItem(0, wItemLibrary.ID,
                                wSFCBOMTask.ProductID, wSFCBOMTask.LineID, wSFCBOMTask.CustomerID, wSFCBOMTask.OrderID,
                                wSFCBOMTask.WBSNo,
                                wSFCBOMTask.PartNo, wSFCBOMTask.PartID, wSFCBOMTask.PartName, wSFCBOMTask.PartPointID,
                                wSFCBOMTask.PartPointName,
                                wSFCBOMTaskItem.MaterialID, wSFCBOMTaskItem.MaterialName, wSFCBOMTaskItem.MaterialNo,
                                wCurrentFQTY, wItemLibrary.UnitID,
                                wItemLibrary.UnitText, wItemLibrary.MinPacking, Calendar.getInstance(), "",
                                wAPSBOMItem.ID);
                        wWMSLineEdgeLibraryItem.UseTrackingNumber = wSFCBOMTask.Code;
                        WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);

                        // ERP过账
                        ZIF_MM_GET_WMS281_WSStub.ZFMM_GET_WMS281Response wms281Response = WMSLineEdgeLibraryDAO
                                .getInstance().ERPUse(wLoginUser, wAPSBOMItem, wSFCBOMTask,
                                        wSFCBOMTaskItem,
                                        wItemLibrary,
                                        wErrorCode);

                        // 更新消耗记录过账标识
                        if (String.valueOf(wms281Response.getIT_OUTPUT().getItem()[0].getZOK()).equals("N")) {
                            wWMSLineEdgeLibraryItem.IsPost = 2;
                            wWMSLineEdgeLibraryItem.PostMsg = String
                                    .valueOf(wms281Response.getIT_OUTPUT().getItem()[0].getZMSG());
                        } else if (String.valueOf(wms281Response.getIT_OUTPUT().getItem()[0].getZOK()).equals("Y")) {
                            wWMSLineEdgeLibraryItem.IsPost = 1;
                            wWMSLineEdgeLibraryItem.PostMsg = "过账成功";
                        }
                        WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);

                        wGZList.add(wms281Response);

                        wMaterialNumber -= wItemLibrary.FQTY;
                    } else {
                        wItemLibrary.FQTY -= wMaterialNumber;
                        wItemLibrary.EditTime = Calendar.getInstance();
                        WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wItemLibrary, wErrorCode);

                        WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem = new WMSLineEdgeLibraryItem(0, wItemLibrary.ID,
                                wSFCBOMTask.ProductID, wSFCBOMTask.LineID, wSFCBOMTask.CustomerID, wSFCBOMTask.OrderID,
                                wSFCBOMTask.WBSNo,
                                wSFCBOMTask.PartNo, wSFCBOMTask.PartID, wSFCBOMTask.PartName, wSFCBOMTask.PartPointID,
                                wSFCBOMTask.PartPointName,
                                wSFCBOMTaskItem.MaterialID, wSFCBOMTaskItem.MaterialName, wSFCBOMTaskItem.MaterialNo,
                                wSFCBOMTaskItem.MaterialNumber, wItemLibrary.UnitID,
                                wItemLibrary.UnitText, wItemLibrary.MinPacking, Calendar.getInstance(), "",
                                wAPSBOMItem.ID);
                        wWMSLineEdgeLibraryItem.UseTrackingNumber = wSFCBOMTask.Code;
                        WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);

                        // ERP过账
                        ZIF_MM_GET_WMS281_WSStub.ZFMM_GET_WMS281Response wms281Response = WMSLineEdgeLibraryDAO
                                .getInstance().ERPUse(wLoginUser, wAPSBOMItem, wSFCBOMTask,
                                        wSFCBOMTaskItem,
                                        wItemLibrary,
                                        wErrorCode);

                        if (String.valueOf(wms281Response.getIT_OUTPUT().getItem()[0].getZOK()).equals("N")) {
                            wWMSLineEdgeLibraryItem.IsPost = 2;
                            wWMSLineEdgeLibraryItem.PostMsg = String
                                    .valueOf(wms281Response.getIT_OUTPUT().getItem()[0].getZMSG());
                        } else if (String.valueOf(wms281Response.getIT_OUTPUT().getItem()[0].getZOK()).equals("Y")) {
                            wWMSLineEdgeLibraryItem.IsPost = 1;
                            wWMSLineEdgeLibraryItem.PostMsg = "过账成功";
                        }
                        WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);

                        wGZList.add(wms281Response);

                        wMaterialNumber = 0;
                    }
                }
            }

            if (wGZList.stream().anyMatch(p -> String.valueOf(p.getIT_OUTPUT().getItem()[0].getZOK()).equals("N"))) {
                ZIF_MM_GET_WMS281_WSStub.ZFMM_GET_WMS281Response wms281Response = wGZList.stream()
                        .filter(p -> String.valueOf(p.getIT_OUTPUT().getItem()[0].getZOK()).equals("N")).findFirst()
                        .get();
                wSFCBOMTask.IsPost = 2;
                wSFCBOMTask.PostMsg = String.valueOf(wms281Response.getIT_OUTPUT().getItem()[0].getZMSG());
                SFCBOMTaskDAO.getInstance().UpdatePostInfo(wLoginUser, wSFCBOMTask, wErrorCode);
            } else if (wGZList.stream().allMatch(p -> String.valueOf(p.getIT_OUTPUT().getItem()[0].getZOK()).equals(
                    "Y"))) {
                wSFCBOMTask.IsPost = 1;
                wSFCBOMTask.PostMsg = "过账成功";
                SFCBOMTaskDAO.getInstance().UpdatePostInfo(wLoginUser, wSFCBOMTask, wErrorCode);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_OutPrint(BMSEmployee wLoginUser, int wWMSPickDemandID) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wWMSPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wWMSPickDemandID,
                    wErrorCode);
            if (wWMSPickDemand == null || wWMSPickDemand.ID <= 0) {
                wResult.FaultCode += "入库单查询失败，请联系系统管理员!";
                return wResult;
            }

            // 二维码地址赋值
            AsignQRCode(wLoginUser, wWMSPickDemand);

            // 输出Excel
            wResult.Result = WMSPickDemandDAO.getInstance().WMS_ExportExcel(wLoginUser, wWMSPickDemand, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    /**
     * 赋值二维码
     */
    private void AsignQRCode(BMSEmployee wLoginUser, WMSPickDemand wWMSPickDemand) {
        try {
            wWMSPickDemand.QRCode = getQRCodeAddress(wLoginUser, wWMSPickDemand.DemandNo);
            for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                wWMSPickDemandItem.QRCode = getQRCodeAddress(wLoginUser,
                        wWMSPickDemandItem.MaterialNo + "," + wWMSPickDemandItem.RowNo);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    private String getQRCodeAddress(BMSEmployee wLoginUser, String wText) {
        String wResult = "";
        try {
            // SimpleDateFormat wSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // String wCurrentTime = wSDF.format(Calendar.getInstance().getTime());
            // ②嵌入二维码的图片路径
            String imgPath = "";
            // ③文件名称
            String wFileName = UUID.randomUUID().toString().replaceAll("-", "");
            // ④生成的二维码的路径及名称
            String wDirePath = StringUtils.Format("{0}static/export/{1}.jpg",
                    Constants.getConfigPath().replace("config/", ""), wFileName);
            File wDirFile = new File(wDirePath);
            if (!wDirFile.exists()) {
                wDirFile.mkdirs();
            }
            // ⑥生成二维码
            QRCodeUtil.encode(wText, imgPath, wDirePath, true);
            // ⑦返回路径
            wResult = wDirePath;
        } catch (Exception ex) {
            logger.error(ex.toString());
        }

        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_ExportDemandItemList(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            MyExcelSheet wMyExcelSheet = WMSPickDemandItemDAO.getInstance().GetMyExcelSheet(wDemandID);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<>(Collections.singletonList(wMyExcelSheet));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, "配送单明细");
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_CancelPartDemandItem(BMSEmployee wLoginUser, List<Integer> wStepIDList,
                                                           int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wWMSPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);
            if (wWMSPickDemand == null || wWMSPickDemand.ID <= 0) {
                wResult.FaultCode += "参数错误!";
                return wResult;
            }

            if (wWMSPickDemand.Status != WMSPickDemandStatus.Sended.getValue()) {
                wResult.FaultCode += "部分取消功能只能取消状态为“待分拣”的配送单!";
                return wResult;
            }

            // 取消原单
            WMSServiceImpl.getInstance().WMS_CancelDistribution(wLoginUser, wDemandID);
            // 创建新单
            wWMSPickDemand.ItemList.removeIf(p -> wStepIDList.stream().anyMatch(q -> q == p.PartPointID));
            if (wWMSPickDemand.ItemList.size() <= 0) {
                return wResult;
            }
            wWMSPickDemand.ID = 0;
            wWMSPickDemand.OriginalOrderNo = wWMSPickDemand.DemandNo;
            wWMSPickDemand.DemandNo = WMSPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);
            int wNewID = WMSPickDemandDAO.getInstance().Update(wLoginUser, wWMSPickDemand, wErrorCode);
            if (wNewID > 0) {
                for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                    wWMSPickDemandItem.ID = 0;
                    wWMSPickDemandItem.DemandID = wNewID;
                    WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem, wErrorCode);
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_TestERPUse(BMSEmployee wLoginUser, int wAPSBOMID, int wSFCBOMTaskID,
                                                 int wSFCBOMTaskItemID, int wWMSLineEdgeLibraryID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            APSBOMItem apsbomItem = APSBOMItemDAO.getInstance().SelectByID(wLoginUser, wAPSBOMID, wErrorCode);
            SFCBOMTask wSFCBOMTask = (SFCBOMTask) SFCBOMTaskDAO.getInstance().BPM_GetTaskInfo(wLoginUser,
                    wSFCBOMTaskID, "",
                    wErrorCode);
            SFCBOMTaskItem sfcbomTaskItem = SFCBOMTaskItemDAO.getInstance().SelectByID(wLoginUser, wSFCBOMTaskItemID,
                    wErrorCode);
            WMSLineEdgeLibrary wmsLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                    wWMSLineEdgeLibraryID, wErrorCode);

            // ERP过账
            WMSLineEdgeLibraryDAO.getInstance().ERPUse(wLoginUser, apsbomItem, wSFCBOMTask, sfcbomTaskItem,
                    wmsLineEdgeLibrary,
                    wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_PickDemandExportItemAll(BMSEmployee wLoginUser, String wDemandIDs) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            MyExcelSheet wMyExcelSheet = WMSPickDemandItemDAO.getInstance().GetMyExcelSheet(wDemandIDs);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<>(Collections.singletonList(wMyExcelSheet));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, "配送单明细");
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<MESMaterialReturn>> WMS_QueryMaterialReturnEmployeeAllNew(BMSEmployee wLoginUser,
                                                                                        Calendar wStartTime,
                                                                                        Calendar wEndTime,
                                                                                        int wStatus) {
        ServiceResult<List<MESMaterialReturn>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            List<MESMaterialReturn> wSendList;
            List<MESMaterialReturn> wToDoList = new ArrayList<>();
            List<MESMaterialReturn> wDoneList = new ArrayList<>();

            List<BPMTaskBase> wBaseList = MESMaterialReturnDAO.getInstance().BPM_GetSendTaskList(wLoginUser,
                    wLoginUser.ID,
                    wStartTime, wEndTime, wErrorCode);
            wSendList = CloneTool.CloneArray(wBaseList, MESMaterialReturn.class);
            // 查询数据
            List<MESMaterialReturn> wList = new ArrayList<>();

            List<BPMTaskBase> wBPMTaskBaseList = MESMaterialReturnDAO.getInstance().BPM_GetUndoTaskList(wLoginUser,
                    wLoginUser.ID, wErrorCode);
            for (BPMTaskBase wBPMTaskBase : wBPMTaskBaseList) {
                wList.add((MESMaterialReturn) wBPMTaskBase);
            }
            List<BPMTaskBase> wDoneBaseList = MESMaterialReturnDAO.getInstance().BPM_GetDoneTaskList(wLoginUser,
                    wLoginUser.ID, wStartTime, wEndTime, wErrorCode);
            for (BPMTaskBase wBPMTaskBase : wDoneBaseList) {
                wList.add((MESMaterialReturn) wBPMTaskBase);
            }
            if (wList.size() > 0) {
                wToDoList = wList.stream().filter(p -> p.StepID > 0).collect(Collectors.toList());
                wDoneList = wList.stream().filter(p -> p.StepID <= 0).collect(Collectors.toList());
            }

            List<Integer> wIDList = new ArrayList<>();

            for (MESMaterialReturn wMTCTask : wToDoList) {
                if (wIDList.contains(wMTCTask.ID))
                    continue;
                wMTCTask.TagTypes = TaskQueryType.ToHandle.getValue();
                wResult.Result.add(wMTCTask);
                wIDList.add(wMTCTask.ID);
            }

            for (MESMaterialReturn wMTCTask : wDoneList) {
                if (wIDList.contains(wMTCTask.ID))
                    continue;
                wMTCTask.TagTypes = TaskQueryType.Handled.getValue();
                wResult.Result.add(wMTCTask);
                wIDList.add(wMTCTask.ID);
            }

            for (MESMaterialReturn wMTCTask : wSendList) {
                if (wIDList.contains(wMTCTask.ID))
                    continue;
                wMTCTask.TagTypes = TaskQueryType.Sended.getValue();
                wResult.Result.add(wMTCTask);
                wIDList.add(wMTCTask.ID);
            }

            wResult.Result.removeIf(p -> p.Status == 0);

            // 状态
            if (wStatus >= 0) {
                if (wStatus == 0) {
                    wResult.Result = wResult.Result.stream()
                            .filter(p -> p.Status != 20 && p.Status != 21 && p.Status != 22)
                            .collect(Collectors.toList());
                } else if (wStatus == 1) {
                    wResult.Result = wResult.Result.stream()
                            .filter(p -> p.Status == 20 || p.Status == 21 || p.Status == 22)
                            .collect(Collectors.toList());
                }
            }

            wResult.Result.sort((o1, o2) -> o2.CreateTime.compareTo(o1.CreateTime));
            wResult.Result.sort((o1, o2) -> {
                if (o1.TagTypes == 1) {
                    return -1;
                } else if (o2.TagTypes == 1) {
                    return 1;
                }
                return 0;
            });

            // 排序，已完工排在最后
            List<MESMaterialReturn> wFinishedList = wResult.Result.stream().filter(p -> p.Status == 20)
                    .collect(Collectors.toList());
            wResult.Result.removeIf(p -> p.Status == 20);
            wResult.Result.addAll(wFinishedList);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_IncomingLineSideLibrary_1(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wWMSPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser,
                    wDemandID, wErrorCode);
            if (wWMSPickDemand == null || wWMSPickDemand.ID <= 0 || wWMSPickDemand.ItemList == null
                    || wWMSPickDemand.ItemList.size() <= 0) {
                return wResult;
            }

            // 去除非反冲料
            List<Integer> wMaterialIDList = wWMSPickDemand.ItemList.stream().map(p -> p.MaterialID).distinct()
                    .collect(Collectors.toList());
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            List<WMSPickDemandItem> wItemList = new ArrayList<>();
            for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                if (wMaterialTypeMap.containsKey(wWMSPickDemandItem.MaterialID)
                        && wMaterialTypeMap.get(wWMSPickDemandItem.MaterialID) == 2) {
                    wItemList.add(wWMSPickDemandItem);
                }
            }

            // 获取工区工位字典
            Map<Integer, Integer> wPartAreaMap = WMSBatchPickDemandDAO.getInstance().GetPartAreaMap(wLoginUser,
                    wErrorCode);
            // 物料分工区进行分配
            List<WMSPickDemandItem> wWMSBatchPickDemandItemList = wItemList.stream().filter(p -> p.PickedNumber > 0)
                    .collect(Collectors.toList());

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);
            for (WMSPickDemandItem wWMSBatchPickDemandItem : wWMSBatchPickDemandItemList) {
                List<WMSPickDemandItem> wSameList = wWMSBatchPickDemandItemList.stream()
                        .filter(p -> p.MaterialID == wWMSBatchPickDemandItem.MaterialID).collect(Collectors.toList());
                Map<Integer, Double> wAreaNumberMap = new HashMap<>();
                for (WMSPickDemandItem wSFCBatchBOMTaskBPMItem : wSameList) {
                    if (!wPartAreaMap.containsKey(wSFCBatchBOMTaskBPMItem.PartID)) {
                        continue;
                    }
                    int wAreaID = wPartAreaMap.get(wSFCBatchBOMTaskBPMItem.PartID);
                    if (wAreaNumberMap.containsKey(wAreaID)) {
                        double wNumber = wAreaNumberMap.get(wAreaID);
                        wNumber += wSFCBatchBOMTaskBPMItem.FQTY;
                        wAreaNumberMap.put(wAreaID, wNumber);
                    } else {
                        wAreaNumberMap.put(wAreaID, wSFCBatchBOMTaskBPMItem.FQTY);
                    }
                }
                double wTotalSize = GetTotalSize(wAreaNumberMap);
                if (wTotalSize <= 0) {
                    continue;
                }
                List<WMSLineEdgeLibrary> wNewLibraryList = new ArrayList<>();
                for (Integer wAreaID : wAreaNumberMap.keySet()) {
                    double wMyNumber = wAreaNumberMap.get(wAreaID);
                    WMSLineEdgeLibrary wWMSLineEdgeLibrary = new WMSLineEdgeLibrary(0,
                            wWMSBatchPickDemandItem.MaterialID,
                            wWMSBatchPickDemandItem.MaterialName, wWMSBatchPickDemandItem.MaterialNo, 0,
                            APSConstans.GetCFGUnit(wSameList.get(0).UnitText).ID, "", 0,
                            Calendar.getInstance(), "",
                            Calendar.getInstance(), "",
                            0, wWMSBatchPickDemandItem.BatchNumber, wWMSBatchPickDemandItem.Stock,
                            wWMSBatchPickDemandItem.Supplier, wWMSBatchPickDemandItem.ProductName,
                            wWMSBatchPickDemandItem.SerialNo,
                            wWMSBatchPickDemandItem.ProductTime);
                    wWMSLineEdgeLibrary.AreaID = wAreaID;
                    wWMSLineEdgeLibrary.SourceType = 1;
                    wWMSLineEdgeLibrary.FQTY = (int) (wWMSBatchPickDemandItem.PickedNumber * wMyNumber / wTotalSize);
                    wWMSLineEdgeLibrary.Total = wWMSLineEdgeLibrary.FQTY;
                    wWMSLineEdgeLibrary.BOMNumber = wWMSBatchPickDemandItem.BOMNumber;
                    wNewLibraryList.add(wWMSLineEdgeLibrary);
                }
                double wLineNumber = 0.0;
                for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wNewLibraryList) {
                    wLineNumber += wWMSLineEdgeLibrary.FQTY;
                }
                // 分配多余的数量给第一个工区
                if (wWMSBatchPickDemandItem.PickedNumber > wLineNumber
                        && wPartAreaMap.containsKey(wSameList.get(0).PartID)) {
                    int wAreaID = wPartAreaMap.get(wSameList.get(0).PartID);
                    if (wNewLibraryList.stream().anyMatch(p -> p.AreaID == wAreaID)) {
                        WMSLineEdgeLibrary wmsLineEdgeLibrary = wNewLibraryList.stream()
                                .filter(p -> p.AreaID == wAreaID).findFirst().get();
                        wmsLineEdgeLibrary.FQTY += wWMSBatchPickDemandItem.PickedNumber - wLineNumber;
                        wmsLineEdgeLibrary.Total = wmsLineEdgeLibrary.FQTY;
                    }
                }
                // 入库
                for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wNewLibraryList) {
                    List<WMSLineEdgeLibrary> wmsLineEdgeLibraries = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                            wLoginUser, -1,
                            wWMSLineEdgeLibrary.MaterialID, "",
                            null, null, wWMSLineEdgeLibrary.AreaID, 1, wWMSLineEdgeLibrary.BatchNumber,
                            wErrorCode);
                    if (wmsLineEdgeLibraries.size() > 0) {
                        wmsLineEdgeLibraries.get(0).FQTY += wWMSLineEdgeLibrary.FQTY;
                        wmsLineEdgeLibraries.get(0).Total += wWMSLineEdgeLibrary.FQTY;

                        // 数量四舍五入
                        wmsLineEdgeLibraries.get(0).FQTY = new BigDecimal(wmsLineEdgeLibraries.get(0).FQTY)
                                .setScale(2, RoundingMode.HALF_UP).doubleValue();
                        wmsLineEdgeLibraries.get(0).Total = new BigDecimal(wmsLineEdgeLibraries.get(0).Total)
                                .setScale(2, RoundingMode.HALF_UP).doubleValue();

                        // 来源单ID维护
                        if (StringUtils.isEmpty(wmsLineEdgeLibraries.get(0).SourceIDs)) {
                            wmsLineEdgeLibraries.get(0).SourceIDs = String.valueOf(wWMSBatchPickDemandItem.DemandID);
                        } else {
                            wmsLineEdgeLibraries.get(0).SourceIDs = wmsLineEdgeLibraries.get(0).SourceIDs + ","
                                    + wWMSBatchPickDemandItem.DemandID;
                        }

                        WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wmsLineEdgeLibraries.get(0), wErrorCode);
                    } else {
                        // 四舍五入
                        wWMSLineEdgeLibrary.FQTY = new BigDecimal(wWMSLineEdgeLibrary.FQTY)
                                .setScale(2, RoundingMode.HALF_UP).doubleValue();
                        wWMSLineEdgeLibrary.Total = new BigDecimal(wWMSLineEdgeLibrary.Total)
                                .setScale(2, RoundingMode.HALF_UP).doubleValue();

                        // 来源单ID维护
                        if (StringUtils.isEmpty(wWMSLineEdgeLibrary.SourceIDs)) {
                            wWMSLineEdgeLibrary.SourceIDs = String.valueOf(wWMSBatchPickDemandItem.DemandID);
                        } else {
                            wWMSLineEdgeLibrary.SourceIDs = wWMSLineEdgeLibrary.SourceIDs + ","
                                    + wWMSBatchPickDemandItem.DemandID;
                        }

                        WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                    }
                }
                // 线边库消耗(反冲料)
                WMSServiceImpl.getInstance().WMS_RecoilMaterialUse(wLoginUser,
                        wWMSBatchPickDemandItem.ID);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public synchronized ServiceResult<Integer> WMS_RecoilMaterialUse(BMSEmployee wLoginUser, int wWMSPickDemandItemID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(wLoginUser,
                    wWMSPickDemandItemID, wErrorCode);
            if (wWMSPickDemandItem == null || wWMSPickDemandItem.ID <= 0) {
                return wResult;
            }

            WMSPickDemand wWMSPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser,
                    wWMSPickDemandItem.DemandID, wErrorCode);

            List<LFSWorkAreaStation> wLFSWorkAreaStationList = LFSServiceImpl.getInstance()
                    .LFS_QueryWorkAreaStationList(wLoginUser).List(LFSWorkAreaStation.class);
            if (wLFSWorkAreaStationList == null || wLFSWorkAreaStationList.size() <= 0) {
                return wResult;
            }
            if (wLFSWorkAreaStationList.stream()
                    .noneMatch(p -> p.StationID == wWMSPickDemand.PartID && p.Active == 1)) {
                return wResult;
            }

            LFSWorkAreaStation wLFSWorkAreaStation = wLFSWorkAreaStationList.stream()
                    .filter(p -> p.StationID == wWMSPickDemand.PartID && p.Active == 1).findFirst().get();
            if (wLFSWorkAreaStation.WorkAreaID <= 0) {
                return wResult;
            }

            // 台车bomID不存在，属于异常数据
            if (wWMSPickDemandItem.BOMItemNum <= 0) {
                return wResult;
            }

            List<APSBOMItem> wList = APSBOMItemDAO.getInstance().APS_QueryBOMItemList(wLoginUser, -1,
                    wWMSPickDemand.OrderID, "", "", -1, -1, -1, wWMSPickDemand.PartID,
                    wWMSPickDemandItem.PartPointID,
                    wWMSPickDemandItem.MaterialID, "", -1, -1, -1, null, -1, -1, -1, wErrorCode);

            // 查询台车BOM
            APSBOMItem wAPSBOMItem = new APSBOMItem();
            if (wList != null && wList.stream().anyMatch(p -> p.OrderNum == wWMSPickDemandItem.BOMItemNum)) {
                wAPSBOMItem = wList.stream().filter(p -> p.OrderNum == wWMSPickDemandItem.BOMItemNum).findFirst().get();
            }

            if (wAPSBOMItem.ID <= 0) {
                return wResult;
            }

            // 查询消耗记录，计算还需要扣减多少个
            List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList = WMSLineEdgeLibraryItemDAO.getInstance()
                    .SelectListByOrderID(wLoginUser, wAPSBOMItem.ID, wErrorCode);
            double wTotalUsedNumber = 0;
            if (wWMSLineEdgeLibraryItemList.size() > 0) {
                wTotalUsedNumber = wWMSLineEdgeLibraryItemList.stream().mapToDouble(p -> p.FQTY).sum();
            }
            double wThisLessNumber = wWMSPickDemandItem.BOMNumber - wTotalUsedNumber;
            if (wThisLessNumber <= 0) {
                return wResult;
            }

            List<WMSLineEdgeLibrary> wWMSLineEdgeLibraryList = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                    wLoginUser, -1, wWMSPickDemandItem.MaterialID, "", null, null, wLFSWorkAreaStation.WorkAreaID, 1,
                    "",
                    wErrorCode);
            // 按照批次排序，依次消耗，直到消耗完毕或没库存消耗为止
            wWMSLineEdgeLibraryList.sort(Comparator.comparing(WMSLineEdgeLibrary::getBatchNumber));

            for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wWMSLineEdgeLibraryList) {
                if (wThisLessNumber <= 0) {
                    return wResult;
                }

                if (wWMSLineEdgeLibrary.FQTY < wThisLessNumber) {
                    wThisLessNumber -= wWMSLineEdgeLibrary.FQTY;

                    // 消耗
                    double wFQTY = wWMSLineEdgeLibrary.FQTY;
                    if (wFQTY <= 0) {
                        continue;
                    }
                    wWMSLineEdgeLibrary.FQTY = 0;
                    wWMSLineEdgeLibrary.EditTime = Calendar.getInstance();
                    WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                    // 消耗记录
                    WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem = new WMSLineEdgeLibraryItem(0,
                            wWMSLineEdgeLibrary.ID,
                            wWMSPickDemand.ProductID, wWMSPickDemand.LineID, wWMSPickDemand.CustomerID,
                            wWMSPickDemand.OrderID,
                            wWMSPickDemand.WBSNo,
                            wWMSPickDemand.PartNo, wWMSPickDemand.PartID, wWMSPickDemand.PartName,
                            wWMSPickDemandItem.PartPointID,
                            wWMSPickDemandItem.PartPointName,
                            wWMSPickDemandItem.MaterialID, wWMSPickDemandItem.MaterialName,
                            wWMSPickDemandItem.MaterialNo,
                            wFQTY, wWMSLineEdgeLibrary.UnitID,
                            wWMSLineEdgeLibrary.UnitText, wWMSLineEdgeLibrary.MinPacking, Calendar.getInstance(), "",
                            wAPSBOMItem.ID);
                    // 维护使用单号
                    if (StringUtils.isEmpty(wWMSPickDemand.OriginalOrderNo)) {
                        wWMSLineEdgeLibraryItem.UseTrackingNumber = wWMSPickDemand.DemandNo;
                    } else {
                        wWMSLineEdgeLibraryItem.UseTrackingNumber = wWMSPickDemand.OriginalOrderNo;
                    }
                    WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);
                    // ERP过账
                    WMSLineEdgeLibraryDAO.getInstance().ERPUse(wLoginUser, wAPSBOMItem, wWMSPickDemand,
                            wWMSPickDemandItem,
                            wWMSLineEdgeLibrary, wWMSLineEdgeLibraryItem,
                            wErrorCode);
                } else {
                    // 消耗
                    double wFQTY = wThisLessNumber;
                    wWMSLineEdgeLibrary.FQTY -= wThisLessNumber;
                    wWMSLineEdgeLibrary.EditTime = Calendar.getInstance();
                    WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                    // 消耗记录
                    WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem = new WMSLineEdgeLibraryItem(0,
                            wWMSLineEdgeLibrary.ID,
                            wWMSPickDemand.ProductID, wWMSPickDemand.LineID, wWMSPickDemand.CustomerID,
                            wWMSPickDemand.OrderID,
                            wWMSPickDemand.WBSNo,
                            wWMSPickDemand.PartNo, wWMSPickDemand.PartID, wWMSPickDemand.PartName,
                            wWMSPickDemandItem.PartPointID,
                            wWMSPickDemandItem.PartPointName,
                            wWMSPickDemandItem.MaterialID, wWMSPickDemandItem.MaterialName,
                            wWMSPickDemandItem.MaterialNo,
                            wFQTY, wWMSLineEdgeLibrary.UnitID,
                            wWMSLineEdgeLibrary.UnitText, wWMSLineEdgeLibrary.MinPacking, Calendar.getInstance(), "",
                            wAPSBOMItem.ID);
                    // 维护使用单号
                    if (StringUtils.isEmpty(wWMSPickDemand.OriginalOrderNo)) {
                        wWMSLineEdgeLibraryItem.UseTrackingNumber = wWMSPickDemand.DemandNo;
                    } else {
                        wWMSLineEdgeLibraryItem.UseTrackingNumber = wWMSPickDemand.OriginalOrderNo;
                    }
                    WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);
                    // ERP过账
                    WMSLineEdgeLibraryDAO.getInstance().ERPUse(wLoginUser, wAPSBOMItem, wWMSPickDemand,
                            wWMSPickDemandItem,
                            wWMSLineEdgeLibrary, wWMSLineEdgeLibraryItem,
                            wErrorCode);
                    wThisLessNumber = 0;
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_BatchConfirmPickDemandItem(BMSEmployee wLoginUser, String wPickDemandIDs,
                                                                 List<WMSPickDemandItem> wItemList) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            for (WMSPickDemandItem wWMSPickDemandItem : wItemList) {
                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wWMSPickDemandItem, wErrorCode);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSPickDemandItem>> WMS_QueryItemAllByDemandIDs(BMSEmployee wLoginUser,
                                                                              String wDemandIDs) {
        ServiceResult<List<WMSPickDemandItem>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSPickDemandItemDAO.getInstance().SelectListByDemandIDs(wLoginUser, wDemandIDs,
                    wErrorCode);
            List<Integer> wIDList = StringUtils.parseIntList(wDemandIDs.split(","));
            List<WMSPickDemand> wWMSPickDemandList = WMSPickDemandDAO.getInstance().SelectList(wLoginUser, -1,
                    "", "", -1, -1, -1, "", -1, -1, null,
                    null, wIDList, wErrorCode);
            wResult.CustomResult.put("WMSPickDemandList", wWMSPickDemandList);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_QueryOutCodes(BMSEmployee wLoginUser, String wIDs) {
        ServiceResult<Integer> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // SimpleDateFormat wSDF = new SimpleDateFormat("yyyy-MM-dd");

            Map<Integer, String> wMap = new HashMap<>();
            String[] wIDStrings = wIDs.split(",");
            for (String wIDStr : wIDStrings) {
                int wID = StringUtils.parseInt(wIDStr);
                if (wID <= 0) {
                    continue;
                }

                IPTOutsourcingMaterial wIPTOutsourcingMaterial = QMSServiceImpl.getInstance()
                        .IPT_OutsourcingMaterialInfo(wLoginUser,
                                wID)
                        .Info(IPTOutsourcingMaterial.class);
                if (wIPTOutsourcingMaterial == null || wIPTOutsourcingMaterial.ID <= 0) {
                    continue;
                }

                MSSMaterial wMSSMaterial = MSS_QueryMaterialByID(wLoginUser, wIPTOutsourcingMaterial.MaterialID)
                        .Info(MSSMaterial.class);

                // 按照技术方案编码规则：车型，车号，物料编码，制造厂商，数量，单位，位置，登记日期，部件流转码

                // 二维码编制规则：M物料编码%Q数量%U单位%A车型%B修程%C局段%D车号%w位置%N序列号%z流水号
                String wTextMain = StringUtils.Format("M{0}%Q{1}%U{2}%A{3}%B{4}%C{5}%D{6}%W{7}%N{8}%Z{9}",
                        wIPTOutsourcingMaterial.MaterialNo, String.valueOf(wIPTOutsourcingMaterial.FQTY),
                        wMSSMaterial.CYUnitText, wIPTOutsourcingMaterial.ProductNo, wIPTOutsourcingMaterial.LineName,
                        wIPTOutsourcingMaterial.CustomerName,
                        wIPTOutsourcingMaterial.PartNo.split("#")[1], "", wIPTOutsourcingMaterial.SerialNo,
                        wIPTOutsourcingMaterial.MaterialFlowTranscoding);

                String wQRCode = getQRCodeString(wLoginUser, wTextMain);

                wMap.put(wIPTOutsourcingMaterial.ID, wQRCode);
            }
            wResult.CustomResult.put("SubCodes", wMap);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ReCodeAndSend(BMSEmployee wLoginUser, String wDemandNo) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSPickDemand> wList = WMSPickDemandDAO.getInstance().GetRepeatList(wLoginUser, wErrorCode);
            if (StringUtils.isNotEmpty(wDemandNo)) {
                wList = wList.stream().filter(p -> p.DemandNo.equals(wDemandNo)).collect(Collectors.toList());
            }

            List<WMSPickDemand> wDemandList = new ArrayList<>(wList.stream()
                    .collect(Collectors.toMap(WMSPickDemand::getDemandNo, account -> account, (k1, k2) -> k2))
                    .values());
            for (WMSPickDemand wWMSPickDemand : wDemandList) {
                List<WMSPickDemand> wSameList = wList.stream().filter(p -> p.DemandNo.equals(wWMSPickDemand.DemandNo))
                        .collect(Collectors.toList());
                int wIndex = 1;
                for (WMSPickDemand wItem : wSameList) {
                    WMSPickDemand wUpdateDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wItem.ID,
                            wErrorCode);
                    wUpdateDemand.DemandNo = StringUtils.Format("{0}{1}", wItem.DemandNo, String.format("%02d",
                            wIndex));
                    WMSPickDemandDAO.getInstance().Update(wLoginUser, wUpdateDemand, wErrorCode);
                    // 手动重推该单据
                    WMSServiceImpl.getInstance().WMS_ManualPush(wLoginUser, wItem.ID);

                    wIndex++;
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateSourceID(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSLineEdgeLibrary> wWMSLineEdgeLibraryList = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                    wLoginUser, -1, -1, "", null,
                    null, -1, -1, "", wErrorCode);
            for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wWMSLineEdgeLibraryList) {
                String wIDs = "";
                if (wWMSLineEdgeLibrary.SourceType == 1) {
                    wIDs = WMSLineEdgeLibraryDAO.getInstance().WMS_QueryReciolSourceIDs(wLoginUser,
                            wWMSLineEdgeLibrary.MaterialNo, wWMSLineEdgeLibrary.BatchNumber, wErrorCode);
                } else if (wWMSLineEdgeLibrary.SourceType == 2) {
                    wIDs = WMSLineEdgeLibraryDAO.getInstance().WMS_QueryBatchSourceIDs(wLoginUser,
                            wWMSLineEdgeLibrary.MaterialNo, wWMSLineEdgeLibrary.BatchNumber, wErrorCode);
                }
                wWMSLineEdgeLibrary.SourceIDs = wIDs;
                WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_RecoilUseUpdate(BMSEmployee wLoginUser, int wWMSLineEdgeLibraryID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSLineEdgeLibrary wWMSLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                    wWMSLineEdgeLibraryID, wErrorCode);
            List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList = WMSLineEdgeLibraryDAO.getInstance()
                    .WMS_QueryWMSLineEdgeLibraryItemByMateiralNoAndBatchNumber(wLoginUser,
                            wWMSLineEdgeLibrary.MaterialNo, wWMSLineEdgeLibrary.BatchNumber, wErrorCode);
            wWMSLineEdgeLibraryItemList = new ArrayList<WMSLineEdgeLibraryItem>(wWMSLineEdgeLibraryItemList.stream()
                    .collect(Collectors.toMap(WMSLineEdgeLibraryItem::getPickDemandItemID, account -> account, (k1,
                                                                                                                k2) -> k2))
                    .values());
            // 遍历增加消耗
            double wFQTY = 0;
            for (WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem : wWMSLineEdgeLibraryItemList) {
                OMSOrder wOMSOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wWMSLineEdgeLibraryItem.OrderID,
                        wErrorCode);
                wWMSLineEdgeLibraryItem.ID = 0;
                wWMSLineEdgeLibraryItem.ProductID = wOMSOrder.ProductID;
                wWMSLineEdgeLibraryItem.LineID = wOMSOrder.LineID;
                wWMSLineEdgeLibraryItem.CustomerID = wOMSOrder.CustomerID;
                wWMSLineEdgeLibraryItem.WBSNo = wOMSOrder.OrderNo;
                wWMSLineEdgeLibraryItem.PartNo = wOMSOrder.PartNo;
                wWMSLineEdgeLibraryItem.WMSLineEdgeID = wWMSLineEdgeLibrary.ID;
                WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);
                wFQTY += wWMSLineEdgeLibraryItem.FQTY;
            }
            wWMSLineEdgeLibrary.FQTY -= wFQTY;
            if (wWMSLineEdgeLibrary.FQTY < 0)
                wWMSLineEdgeLibrary.FQTY = 0;
            WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSBatchPickDemand>> WMS_QueryBatchPickDemandListByIDs(BMSEmployee wLoginUser,
                                                                                     String wIDs, int wMaterialID,
                                                                                     String wBatchNumber) {
        ServiceResult<List<WMSBatchPickDemand>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            String[] wStrs = wIDs.split(",");
            List<Integer> wIDList = StringUtils.parseIntList(wStrs);
            wResult.Result = WMSBatchPickDemandDAO.getInstance().SelectListByIDList(wLoginUser, wIDList, wErrorCode);
            List<WMSBatchPickDemandItem> wWMSBatchPickDemandItemList = WMSBatchPickDemandItemDAO.getInstance()
                    .SelectListByDemandIDList(wLoginUser, wIDList, wErrorCode);

            // 查询出库明细列表
            List<Integer> wItemIDList = wWMSBatchPickDemandItemList.stream().map(p -> p.ID).distinct()
                    .collect(Collectors.toList());
            List<WMSBatchPickDemandItemStock> wWMSBatchPickDemandItemStockList = WMSBatchPickDemandItemStockDAO
                    .getInstance().SelectListByItemIDList(wLoginUser, wItemIDList,
                            wErrorCode);

            for (WMSBatchPickDemand wWMSBatchPickDemand : wResult.Result) {
                if (wWMSBatchPickDemandItemList.stream()
                        .anyMatch(p -> p.DemandID == wWMSBatchPickDemand.ID && p.MaterialID == wMaterialID)) {
                    WMSBatchPickDemandItem wWMSBatchPickDemandItem = wWMSBatchPickDemandItemList.stream()
                            .filter(p -> p.DemandID == wWMSBatchPickDemand.ID
                                    && p.MaterialID == wMaterialID)
                            .findFirst().get();
                    if (wWMSBatchPickDemandItemStockList.stream().anyMatch(p -> p.TaskID == wWMSBatchPickDemandItem.ID
                            && p.BatchNumber.equals(wBatchNumber))) {
                        wWMSBatchPickDemand.SubMaterialNumber = wWMSBatchPickDemandItemStockList.stream()
                                .filter(p -> p.TaskID == wWMSBatchPickDemandItem.ID
                                        && p.BatchNumber.equals(wBatchNumber))
                                .mapToDouble(p -> p.PickedNumber).sum();
                    } else {
                        wWMSBatchPickDemand.SubMaterialNumber = wWMSBatchPickDemandItem.PickedNumber;
                    }
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSPickDemand>> WMS_QueryWMSPickDemandListByIDs(BMSEmployee wLoginUser, String wIDs,
                                                                              int wMaterialID, String wBatchNumber) {
        ServiceResult<List<WMSPickDemand>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            String[] wStrs = wIDs.split(",");
            List<Integer> wIDList = StringUtils.parseIntList(wStrs);
            wResult.Result = WMSPickDemandDAO.getInstance().SelectList(wLoginUser, -1, "", "",
                    -1, -1, -1, "", -1, -1, null, null, wIDList, wErrorCode);
            // 查询子项列表
            List<WMSPickDemandItem> wWMSPickDemandItemList = WMSPickDemandItemDAO.getInstance()
                    .SelectListByDemandIDList(wLoginUser, wIDList, wErrorCode);

            // 查询出库明细列表
            List<Integer> wItemIDList = wWMSPickDemandItemList.stream().map(p -> p.ID).distinct()
                    .collect(Collectors.toList());
            List<WMSPickDemandItemStock> wWMSPickDemandItemStockList = WMSPickDemandItemStockDAO.getInstance()
                    .SelectListByItemIDList(wLoginUser, wItemIDList,
                            wErrorCode);

            for (WMSPickDemand wWMSPickDemand : wResult.Result) {
                if (wWMSPickDemandItemList.stream()
                        .anyMatch(p -> p.DemandID == wWMSPickDemand.ID && p.MaterialID == wMaterialID)) {
                    WMSPickDemandItem wWMSPickDemandItem = wWMSPickDemandItemList.stream()
                            .filter(p -> p.DemandID == wWMSPickDemand.ID
                                    && p.MaterialID == wMaterialID)
                            .findFirst().get();
                    if (wWMSPickDemandItemStockList.stream().anyMatch(p -> p.TaskID == wWMSPickDemandItem.ID
                            && p.BatchNumber.equals(wBatchNumber))) {
                        wWMSPickDemand.SubMaterialNumber = wWMSPickDemandItemStockList.stream()
                                .filter(p -> p.TaskID == wWMSPickDemandItem.ID
                                        && p.BatchNumber.equals(wBatchNumber))
                                .mapToDouble(p -> p.PickedNumber).sum();
                    } else {
                        wWMSPickDemand.SubMaterialNumber = wWMSPickDemandItem.PickedNumber;
                    }
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_RePostTheBackFlushedMaterials(BMSEmployee wLoginUser,
                                                                    List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            for (WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem : wWMSLineEdgeLibraryItemList) {
                WMSLineEdgeLibrary wWMSLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                        wWMSLineEdgeLibraryItem.WMSLineEdgeID, wErrorCode);
                if (wWMSLineEdgeLibrary == null || wWMSLineEdgeLibrary.ID <= 0) {
                    continue;
                }

                if (wWMSLineEdgeLibraryItem.APSBOMItemID <= 0) {
                    continue;
                }

                List<APSBOMItem> wList = APSBOMItemDAO.getInstance().APS_QueryBOMItemList(wLoginUser, -1,
                        wWMSLineEdgeLibraryItem.OrderID, "", "", -1, -1, -1, wWMSLineEdgeLibraryItem.PartID,
                        wWMSLineEdgeLibraryItem.PartPointID,
                        wWMSLineEdgeLibraryItem.MaterialID, "", -1, -1, -1, null, -1, -1, -1, wErrorCode);

                APSBOMItem wAPSBOMItem = new APSBOMItem();
                if (wList != null && wList.stream().anyMatch(
                        p -> p.OrderNum == wWMSLineEdgeLibraryItem.APSBOMItemID && StringUtils.isEmpty(p.DeleteID))) {
                    wAPSBOMItem = wList.stream().filter(
                                    p -> p.OrderNum == wWMSLineEdgeLibraryItem.APSBOMItemID && StringUtils.isEmpty(p.DeleteID))
                            .findFirst().get();
                } else if (wList != null && wList.stream().anyMatch(p -> StringUtils.isEmpty(p.DeleteID)))
                    wAPSBOMItem = wList.stream().filter(p -> StringUtils.isEmpty(p.DeleteID)).findFirst().get();
                if (wAPSBOMItem.ID <= 0) {

                    // ①删除消耗记录
                    WMSLineEdgeLibraryItemDAO.getInstance().DeleteList(wLoginUser,
                            new ArrayList<>(Collections.singletonList(wWMSLineEdgeLibraryItem)), wErrorCode);
                    // ②主库存补库存
                    wWMSLineEdgeLibrary.FQTY += wWMSLineEdgeLibraryItem.FQTY;
                    WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);

                    continue;
                }
                // ③过账
                WMSLineEdgeLibraryDAO.getInstance().ERPUse(wLoginUser, wAPSBOMItem, new WMSPickDemand(),
                        new WMSPickDemandItem(),
                        wWMSLineEdgeLibrary, wWMSLineEdgeLibraryItem,
                        wErrorCode);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateAPSBOMItemID(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList = WMSLineEdgeLibraryItemDAO.getInstance()
                    .SelectList(wLoginUser, -1, -1, -1, -1,
                            -1, -1, -1, -1, -1, null, null, wErrorCode);

            int wIndex = 1;
            for (WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem : wWMSLineEdgeLibraryItemList) {
                int wAPSBOMItemID = WMSLineEdgeLibraryItemDAO.getInstance().WMS_QueryAPSBOMItemID(wLoginUser,
                        wWMSLineEdgeLibraryItem, wErrorCode);
                if (wAPSBOMItemID <= 0) {
                    continue;
                }
                wWMSLineEdgeLibraryItem.APSBOMItemID = wAPSBOMItemID;
                WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);

                System.out.println(wIndex++);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_RePostAll(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList = WMSLineEdgeLibraryItemDAO.getInstance()
                    .SelectList(wLoginUser, -1, -1, -1, -1,
                            -1, -1, -1, -1, -1, null, null, wErrorCode);
            wWMSLineEdgeLibraryItemList = wWMSLineEdgeLibraryItemList.stream().filter(p -> p.IsPost == 0)
                    .collect(Collectors.toList());
            int wIndex = 0;
            for (WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem : wWMSLineEdgeLibraryItemList) {
                WMSLineEdgeLibrary wWMSLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                        wWMSLineEdgeLibraryItem.WMSLineEdgeID, wErrorCode);
                if (wWMSLineEdgeLibrary == null || wWMSLineEdgeLibrary.ID <= 0) {
                    System.out.println(wIndex++);
                    continue;
                }

                if (wWMSLineEdgeLibraryItem.APSBOMItemID <= 0) {
                    System.out.println(wIndex++);
                    continue;
                }

                APSBOMItem wAPSBOMItem = APSBOMItemDAO.getInstance().SelectByID(wLoginUser,
                        wWMSLineEdgeLibraryItem.APSBOMItemID, wErrorCode);
                if (wAPSBOMItem == null || wAPSBOMItem.ID <= 0) {
                    System.out.println(wIndex++);
                    continue;
                }
                // ③过账
                WMSLineEdgeLibraryDAO.getInstance().ERPUse(wLoginUser, wAPSBOMItem, new WMSPickDemand(),
                        new WMSPickDemandItem(),
                        wWMSLineEdgeLibrary, wWMSLineEdgeLibraryItem,
                        wErrorCode);
                System.out.println(wIndex++);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ResendCanceled(BMSEmployee wLoginUser, ExcelData wExcelData) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            if (wExcelData == null || wExcelData.sheetData == null || wExcelData.sheetData.size() <= 0) {
                wResult.FaultCode += "提示：Excel解析失败!";
                return wResult;
            }

            ExcelSheetData wExcelSheetData = wExcelData.sheetData.get(0);
            int wIndex = 0;
            for (ExcelLineData wExcelLineData : wExcelSheetData.lineData) {
                if (wIndex == 0) {
                    wIndex++;
                    continue;
                }

                String wDemandNo = wExcelLineData.colData.get(2);
                if (StringUtils.isEmpty(wDemandNo)) {
                    wIndex++;
                    continue;
                }

                List<WMSPickDemand> wWMSPickDemandList = WMSPickDemandDAO.getInstance().SelectList(wLoginUser, -1, "",
                        wDemandNo, -1, -1, -1, "", -1, -1, null, null, null, wErrorCode);
                if (wWMSPickDemandList == null || wWMSPickDemandList.size() <= 0) {
                    wIndex++;
                    continue;
                }

                WMSPickDemand wWMSPickDemand = wWMSPickDemandList.get(0);
                if (wWMSPickDemand.Status != 6) {
                    wIndex++;
                    continue;
                }

                // 重新推送
                WMSServiceImpl.getInstance().WMS_ManualPush(wLoginUser, wWMSPickDemand.ID);

                wIndex++;
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_QueryErrorIDs(BMSEmployee wLoginUser) {
        ServiceResult<String> wResult = new ServiceResult<>();
        wResult.Result = "";
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSLineEdgeLibrary> wWMSLineEdgeLibraryList = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                    wLoginUser, -1, -1, "", null,
                    null, -1, -1, "", wErrorCode);
            List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList = WMSLineEdgeLibraryItemDAO.getInstance()
                    .SelectList(wLoginUser, -1, -1, -1, -1,
                            -1, -1, -1, -1, -1, null, null, wErrorCode);

            List<Integer> wIDList = new ArrayList<>();
            for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wWMSLineEdgeLibraryList) {
                double wUseNumber = 0.0;
                if (wWMSLineEdgeLibraryItemList.stream().anyMatch(p -> p.WMSLineEdgeID == wWMSLineEdgeLibrary.ID)) {
                    wUseNumber = wWMSLineEdgeLibraryItemList.stream()
                            .filter(p -> p.WMSLineEdgeID == wWMSLineEdgeLibrary.ID).mapToDouble(p -> p.FQTY).sum();
                }
                if (!(Math.abs((wUseNumber + wWMSLineEdgeLibrary.FQTY) - wWMSLineEdgeLibrary.Total) < 0.0001)) {
                    wIDList.add(wWMSLineEdgeLibrary.ID);
                }
            }
            wResult.Result = StringUtils.Join(",", wIDList);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_AutoProofread(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①查询线边库列表
            List<WMSLineEdgeLibrary> wWMSLineEdgeLibraryList = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                    wLoginUser, -1, -1, "", null,
                    null, -1, -1, "", wErrorCode);
            // ③校对库存
            for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wWMSLineEdgeLibraryList) {
                // ①查询是否有盘点记录，若有，则不校对，以盘点记录为准
                List<WMSInventoryCheck> wWMSInventoryCheckList = WMSInventoryCheckDAO.getInstance()
                        .SelectList(wLoginUser, -1, wWMSLineEdgeLibrary.ID, -1, -1, -1, wErrorCode);
                if (wWMSInventoryCheckList != null && wWMSInventoryCheckList.size() > 0) {
                    continue;
                }
                // ②查询线边总使用量
                double wTotalUsed = WMSLineEdgeLibraryItemDAO.getInstance().WMS_QueryTotalCount(wLoginUser,
                        wWMSLineEdgeLibrary.ID, wErrorCode);
                wTotalUsed = new BigDecimal(wTotalUsed)
                        .setScale(2, RoundingMode.HALF_UP).doubleValue();
                if (wTotalUsed != wWMSLineEdgeLibrary.FQTY) {
                    wWMSLineEdgeLibrary.FQTY = wWMSLineEdgeLibrary.Total - wTotalUsed;
                    if (wWMSLineEdgeLibrary.FQTY < 0) {
                        wWMSLineEdgeLibrary.FQTY = 0;
                    }
                    WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_ManualPushBatch(BMSEmployee wLoginUser, String wDemandIDs) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<Integer> wDemandIDList = StringUtils.parseIntList(wDemandIDs.split(","));
            for (int wDemandID : wDemandIDList) {
                WMSServiceImpl.getInstance().WMS_ManualPush(wLoginUser, wDemandID);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSBatchPickDemand>> WMS_QueryBatchLineEdgeSource(BMSEmployee wLoginUser,
                                                                                int wWMSLineEdgeID) {
        ServiceResult<List<WMSBatchPickDemand>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSLineEdgeLibrary wWMSLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                    wWMSLineEdgeID, wErrorCode);
            if (wWMSLineEdgeLibrary == null || wWMSLineEdgeLibrary.ID <= 0) {
                return wResult;
            }

            wResult.Result = WMSBatchPickDemandDAO.getInstance().WMS_QueryBatchLineEdgeSource(wLoginUser,
                    wWMSLineEdgeLibrary, wErrorCode);
            wResult.Result.removeIf(p -> p.SubMaterialNumber <= 0);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSPickDemand>> WMS_QueryRecoilLineEdgeSource(BMSEmployee wLoginUser,
                                                                            int wWMSLineEdgeID) {
        ServiceResult<List<WMSPickDemand>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSLineEdgeLibrary wWMSLineEdgeLibrary = WMSLineEdgeLibraryDAO.getInstance().SelectByID(wLoginUser,
                    wWMSLineEdgeID, wErrorCode);
            if (wWMSLineEdgeLibrary == null || wWMSLineEdgeLibrary.ID <= 0) {
                return wResult;
            }

            wResult.Result = WMSPickDemandDAO.getInstance().WMS_QueryRecoilLineEdgeSource(wLoginUser,
                    wWMSLineEdgeLibrary, wErrorCode);
            wResult.Result.removeIf(p -> p.SubMaterialNumber <= 0);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_UpdateTotal(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSLineEdgeLibrary> wWMSLineEdgeLibraryList = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                    wLoginUser, -1, -1, "", null,
                    null, -1, -1, "", wErrorCode);
            for (WMSLineEdgeLibrary wWMSLineEdgeLibrary : wWMSLineEdgeLibraryList) {
                if (wWMSLineEdgeLibrary.SourceType == 1) {
                    List<WMSPickDemand> wWMSPickDemandList = WMS_QueryRecoilLineEdgeSource(wLoginUser,
                            wWMSLineEdgeLibrary.ID).Result;
                    double wSum = wWMSPickDemandList.stream().mapToDouble(p -> p.SubMaterialNumber).sum();
                    wSum = new BigDecimal(wSum)
                            .setScale(2, RoundingMode.HALF_UP).doubleValue();
                    if (wSum != wWMSLineEdgeLibrary.Total) {
                        wWMSLineEdgeLibrary.Total = wSum;
                        WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                    }
                } else {
                    List<WMSBatchPickDemand> wWMSBatchPickDemandList = WMS_QueryBatchLineEdgeSource(wLoginUser,
                            wWMSLineEdgeLibrary.ID).Result;
                    double wSum = wWMSBatchPickDemandList.stream().mapToDouble(p -> p.SubMaterialNumber).sum();
                    wSum = new BigDecimal(wSum)
                            .setScale(2, RoundingMode.HALF_UP).doubleValue();
                    if (wSum != wWMSLineEdgeLibrary.Total) {
                        wWMSLineEdgeLibrary.Total = wSum;
                        WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                    }
                }
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public void WMS_AutoTransferItems(BMSEmployee wLoginUser) {
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSLineEdgeLibraryItem> wList = WMSLineEdgeLibraryItemDAO.getInstance().SelectErrorList(wLoginUser,
                    wErrorCode);

            WMSServiceImpl.getInstance().WMS_RePostTheBackFlushedMaterials(wLoginUser, wList);
        } catch (Exception e) {
            logger.error(e.toString());
        }
    }

    @Override
    public ServiceResult<List<WMSLineEdgeLibraryItem>> WMS_QueryUseList(BMSEmployee wLoginUser, int wProductID,
                                                                        int wLineID, int wCustomerID,
                                                                        String wOrderIDs, int wPartID,
                                                                        int wPartPointID, String wMaterial, int wAreaID,
                                                                        int wIsPost, String wBatchNumber,
                                                                        String wPostMsgLike, Calendar wStartTime,
                                                                        Calendar wEndTime, Pagination wPagination) {
        ServiceResult<List<WMSLineEdgeLibraryItem>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSLineEdgeLibraryItemDAO.getInstance().SelectListByPage(wLoginUser, wProductID, wLineID,
                    wCustomerID, wOrderIDs, wPartID, wPartPointID, wMaterial, wAreaID, wIsPost, wBatchNumber,
                    wPostMsgLike,
                    wStartTime,
                    wEndTime, wPagination,
                    wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_SynchronizedToWMS(BMSEmployee wLoginUser, int wDemandID,
                                                        boolean wIsUpdateWorkSpace) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);

            OMSOrder wOMSOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wPickDemand.OrderID, wErrorCode);

            List<WMSLinePartLL> wHeaderList = new ArrayList<>();
            WMSLinePartLL wWMSLinePartLL = GetWMSLinePartLL(wPickDemand, wIsUpdateWorkSpace);

            // 同步表头，需清空子项
            if (wWMSLinePartLL.details != null && wWMSLinePartLL.details.size() > 0) {
                wWMSLinePartLL.details = new ArrayList<>();
            }

            wHeaderList.add(wWMSLinePartLL);
            WMSLinePartLLs wWMSLinePartLLs = new WMSLinePartLLs(wHeaderList);

            WMSReturn wReturn = MyHelperServiceImpl.getInstance().WMS_SynchronizTime(wWMSLinePartLLs, wPickDemand);
            if (wReturn.returnFlag.equals("1")) {

                wPickDemand.SendStatus = 1;
                wPickDemand.SendDesc = "推送成功";
            } else {
                wPickDemand.SendStatus = 2;

                if (StringUtils.isEmpty(wReturn.returnDesc))
                    wPickDemand.SendDesc = "网络错误";
                else
                    wPickDemand.SendDesc = JSON.toJSONString(wReturn.returnDesc);

                wResult.FaultCode += wReturn.returnDesc;
            }

            WMSPickDemandDAO.getInstance().Update(wLoginUser, wPickDemand, wErrorCode);
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<List<WMSPickDemandItemStock>> WMS_QueryQueryAllByTaskIDList(BMSEmployee wLoginUser,
                                                                                     String wTaskIDs) {
        ServiceResult<List<WMSPickDemandItemStock>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSPickDemandItemStockDAO.getInstance().SelectListByItemIDList(wLoginUser,
                    StringUtils.parseIntList(wTaskIDs.split(",")), wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_BatchGetNewCode(BMSEmployee wLoginUser) {
        ServiceResult<String> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = WMSBatchPickDemandDAO.getInstance().GetNewCode(wLoginUser, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_TestUpdatePickDemand(BMSEmployee wLoginUser, int wDemandID,
                                                           String wDemandItemIDs) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<Integer> wItemIDList = StringUtils.parseIntList(wDemandItemIDs.split(","));

            WMSPickDemand wPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser, wDemandID, wErrorCode);
            wPickDemand.ItemList = wPickDemand.ItemList.stream()
                    .filter(p -> wItemIDList.stream().anyMatch(q -> q == p.ID)).collect(Collectors.toList());

            OMSOrder wOMSOrder = OMSOrderDAO.getInstance().SelectByID(wLoginUser, wPickDemand.OrderID, wErrorCode);

            List<WMSLinePartLL> wHeaderList = new ArrayList<>();
            WMSLinePartLL wWMSLinePartLL = GetWMSLinePartLL_Update(wPickDemand);

            wHeaderList.add(wWMSLinePartLL);
            WMSLinePartLLs wWMSLinePartLLs = new WMSLinePartLLs(wHeaderList);

            WMSReturn wReturn = MyHelperServiceImpl.getInstance().WMS_SynchronizTime(wWMSLinePartLLs, wPickDemand);
            if (wReturn.returnFlag.equals("1")) {

                wPickDemand.SendStatus = 1;
                wPickDemand.SendDesc = "推送成功";

                wPickDemand.ItemList.forEach(p -> {
                    p.UpdateFlag = 1;
                    p.UpdateErrorMsg = "修改成功";
                });

            } else {
                wPickDemand.SendStatus = 2;

                if (StringUtils.isEmpty(wReturn.returnDesc))
                    wPickDemand.SendDesc = "网络错误";
                else
                    wPickDemand.SendDesc = JSON.toJSONString(wReturn.returnDesc);

                wPickDemand.ItemList.forEach(p -> {
                    p.UpdateFlag = 2;
                    p.UpdateErrorMsg = wReturn.returnDesc;
                });

                wResult.FaultCode += wReturn.returnDesc;
            }

            WMSPickDemandDAO.getInstance().Update(wLoginUser, wPickDemand, wErrorCode);
            // 更新子项标记
            for (WMSPickDemandItem wmsPickDemandItem : wPickDemand.ItemList) {
                WMSPickDemandItemDAO.getInstance().Update(wLoginUser, wmsPickDemandItem, wErrorCode);
            }
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_IncomingLineSideLibrary_2(BMSEmployee wLoginUser, int wDemandID) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wWMSPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser,
                    wDemandID, wErrorCode);
            if (wWMSPickDemand == null || wWMSPickDemand.ID <= 0 || wWMSPickDemand.ItemList == null
                    || wWMSPickDemand.ItemList.size() <= 0) {
                return wResult;
            }

            // 取反冲料
            List<Integer> wMaterialIDList = wWMSPickDemand.ItemList.stream().map(p -> p.MaterialID).distinct()
                    .collect(Collectors.toList());
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            List<WMSPickDemandItem> wItemList = new ArrayList<>();
            for (WMSPickDemandItem wWMSPickDemandItem : wWMSPickDemand.ItemList) {
                if (wMaterialTypeMap.containsKey(wWMSPickDemandItem.MaterialID)
                        && wMaterialTypeMap.get(wWMSPickDemandItem.MaterialID) == 2) {
                    wItemList.add(wWMSPickDemandItem);
                }
            }

            // 获取工区工位字典
            Map<Integer, Integer> wPartAreaMap = WMSBatchPickDemandDAO.getInstance().GetPartAreaMap(wLoginUser,
                    wErrorCode);
            // 物料分工区进行分配
            List<WMSPickDemandItem> wWMSBatchPickDemandItemList = wItemList.stream().filter(p -> p.PickedNumber > 0)
                    .collect(Collectors.toList());

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);
            for (WMSPickDemandItem wWMSBatchPickDemandItem : wWMSBatchPickDemandItemList) {

                // 查询出库明细，按照出库明细依次入库
                List<WMSPickDemandItemStock> wmsPickDemandItemStocks = WMSPickDemandItemStockDAO.getInstance()
                        .SelectList(wLoginUser, -1, wWMSBatchPickDemandItem.ID, "",
                                "", wErrorCode);
                if (wmsPickDemandItemStocks == null || wmsPickDemandItemStocks.size() <= 0) {
                    continue;
                }

                int wAreaID = 0;
                if (wPartAreaMap.containsKey(wWMSBatchPickDemandItem.PartID)) {
                    wAreaID = wPartAreaMap.get(wWMSBatchPickDemandItem.PartID);
                }
                if (wAreaID <= 0) {
                    continue;
                }

                for (WMSPickDemandItemStock wmsPickDemandItemStock : wmsPickDemandItemStocks) {

                    // 查询是否存在此批次线边物料；若不存在，则创建；否则更新；
                    List<WMSLineEdgeLibrary> wmsLineEdgeLibraries = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                            wLoginUser, -1,
                            wWMSBatchPickDemandItem.MaterialID, "",
                            null, null, wAreaID, 1, wmsPickDemandItemStock.BatchNumber,
                            wErrorCode);
                    if (wmsLineEdgeLibraries.size() > 0) {
                        wmsLineEdgeLibraries.get(0).FQTY += wmsPickDemandItemStock.PickedNumber;
                        wmsLineEdgeLibraries.get(0).Total += wmsPickDemandItemStock.PickedNumber;

                        // 数量四舍五入
                        wmsLineEdgeLibraries.get(0).FQTY = new BigDecimal(wmsLineEdgeLibraries.get(0).FQTY)
                                .setScale(2, RoundingMode.HALF_UP).doubleValue();
                        wmsLineEdgeLibraries.get(0).Total = new BigDecimal(wmsLineEdgeLibraries.get(0).Total)
                                .setScale(2, RoundingMode.HALF_UP).doubleValue();

                        WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wmsLineEdgeLibraries.get(0), wErrorCode);
                    } else {
                        WMSLineEdgeLibrary wWMSLineEdgeLibrary = new WMSLineEdgeLibrary(0,
                                wWMSBatchPickDemandItem.MaterialID,
                                wWMSBatchPickDemandItem.MaterialName, wWMSBatchPickDemandItem.MaterialNo, 0,
                                APSConstans.GetCFGUnit(wWMSBatchPickDemandItem.UnitText).ID, "", 0,
                                Calendar.getInstance(), "",
                                Calendar.getInstance(), "",
                                0, wmsPickDemandItemStock.BatchNumber, wmsPickDemandItemStock.Stock,
                                wmsPickDemandItemStock.Supplier, wmsPickDemandItemStock.ProductName,
                                wmsPickDemandItemStock.SerialNo,
                                wmsPickDemandItemStock.ProductTime);
                        wWMSLineEdgeLibrary.AreaID = wAreaID;
                        wWMSLineEdgeLibrary.SourceType = 1;
                        wWMSLineEdgeLibrary.FQTY = wmsPickDemandItemStock.PickedNumber;
                        wWMSLineEdgeLibrary.Total = wWMSLineEdgeLibrary.FQTY;
                        wWMSLineEdgeLibrary.BOMNumber = wWMSBatchPickDemandItem.BOMNumber;
                        wWMSLineEdgeLibrary.ProjectStockNo = wmsPickDemandItemStock.ProjectStockNo;

                        // 四舍五入
                        wWMSLineEdgeLibrary.FQTY = new BigDecimal(wWMSLineEdgeLibrary.FQTY)
                                .setScale(2, RoundingMode.HALF_UP).doubleValue();
                        wWMSLineEdgeLibrary.Total = new BigDecimal(wWMSLineEdgeLibrary.Total)
                                .setScale(2, RoundingMode.HALF_UP).doubleValue();

                        WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
                    }
                }
            }

            // 线边库消耗(反冲料)
            for (WMSPickDemandItem wmsPickDemandItem : wWMSBatchPickDemandItemList) {
                // 线边库消耗(反冲料)
                WMSServiceImpl.getInstance().WMS_RecoilMaterialUse(wLoginUser,
                        wmsPickDemandItem.ID);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_IncomingLineSideLibrary_3(BMSEmployee wLoginUser, int wDemandID,
                                                                WMSPickDemandItem wWMSPickDemandItem,
                                                                WMSPickDemandItemStock wWMSPickDemandItemStock) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSPickDemand wWMSPickDemand = WMSPickDemandDAO.getInstance().SelectByID(wLoginUser,
                    wDemandID, wErrorCode);
            if (wWMSPickDemand == null || wWMSPickDemand.ID <= 0 || wWMSPickDemand.ItemList == null
                    || wWMSPickDemand.ItemList.size() <= 0) {
                return wResult;
            }

            // 取反冲料
            List<Integer> wMaterialIDList = new ArrayList<>(Collections.singletonList(wWMSPickDemandItem.MaterialID));
            Map<Integer, Integer> wMaterialTypeMap = MRPMaterialPlanDAO.getInstance().GetMaterialTypeMap(wLoginUser,
                    wMaterialIDList, wErrorCode);
            List<WMSPickDemandItem> wItemList = new ArrayList<>();
            if (wMaterialTypeMap.containsKey(wWMSPickDemandItem.MaterialID)
                    && wMaterialTypeMap.get(wWMSPickDemandItem.MaterialID) == 2) {
                wItemList.add(wWMSPickDemandItem);
            }
            if (wItemList.size() <= 0) {
                return wResult;
            }

            // 获取工区工位字典
            Map<Integer, Integer> wPartAreaMap = WMSBatchPickDemandDAO.getInstance().GetPartAreaMap(wLoginUser,
                    wErrorCode);

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);

            int wAreaID = 0;
            if (wPartAreaMap.containsKey(wWMSPickDemandItem.PartID)) {
                wAreaID = wPartAreaMap.get(wWMSPickDemandItem.PartID);
            }
            if (wAreaID <= 0) {
                return wResult;
            }

            // 查询是否存在此批次线边物料；若不存在，则创建；否则更新；
            List<WMSLineEdgeLibrary> wmsLineEdgeLibraries = WMSLineEdgeLibraryDAO.getInstance().SelectList(
                    wLoginUser, -1,
                    wWMSPickDemandItem.MaterialID, "",
                    null, null, wAreaID, 1, wWMSPickDemandItemStock.BatchNumber,
                    wErrorCode);
            if (wmsLineEdgeLibraries.size() > 0) {
                wmsLineEdgeLibraries.get(0).FQTY += wWMSPickDemandItemStock.PickedNumber;
                wmsLineEdgeLibraries.get(0).Total += wWMSPickDemandItemStock.PickedNumber;

                // 数量四舍五入
                wmsLineEdgeLibraries.get(0).FQTY = new BigDecimal(wmsLineEdgeLibraries.get(0).FQTY)
                        .setScale(2, RoundingMode.HALF_UP).doubleValue();
                wmsLineEdgeLibraries.get(0).Total = new BigDecimal(wmsLineEdgeLibraries.get(0).Total)
                        .setScale(2, RoundingMode.HALF_UP).doubleValue();

                WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wmsLineEdgeLibraries.get(0), wErrorCode);
            } else {
                WMSLineEdgeLibrary wWMSLineEdgeLibrary = new WMSLineEdgeLibrary(0,
                        wWMSPickDemandItem.MaterialID,
                        wWMSPickDemandItem.MaterialName, wWMSPickDemandItem.MaterialNo, 0,
                        APSConstans.GetCFGUnit(wWMSPickDemandItem.UnitText).ID, "", 0,
                        Calendar.getInstance(), "",
                        Calendar.getInstance(), "",
                        0, wWMSPickDemandItemStock.BatchNumber, wWMSPickDemandItemStock.Stock,
                        wWMSPickDemandItemStock.Supplier, wWMSPickDemandItemStock.ProductName,
                        wWMSPickDemandItemStock.SerialNo,
                        wWMSPickDemandItemStock.ProductTime);
                wWMSLineEdgeLibrary.AreaID = wAreaID;
                wWMSLineEdgeLibrary.SourceType = 1;
                wWMSLineEdgeLibrary.FQTY = wWMSPickDemandItemStock.PickedNumber;
                wWMSLineEdgeLibrary.Total = wWMSLineEdgeLibrary.FQTY;
                wWMSLineEdgeLibrary.BOMNumber = wWMSPickDemandItem.BOMNumber;
                wWMSLineEdgeLibrary.ProjectStockNo = wWMSPickDemandItemStock.ProjectStockNo;

                // 四舍五入
                wWMSLineEdgeLibrary.FQTY = new BigDecimal(wWMSLineEdgeLibrary.FQTY)
                        .setScale(2, RoundingMode.HALF_UP).doubleValue();
                wWMSLineEdgeLibrary.Total = new BigDecimal(wWMSLineEdgeLibrary.Total)
                        .setScale(2, RoundingMode.HALF_UP).doubleValue();

                WMSLineEdgeLibraryDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibrary, wErrorCode);
            }

            // 线边库消耗(反冲料)
            WMSServiceImpl.getInstance().WMS_RecoilMaterialUse(wLoginUser, wWMSPickDemandItem.ID);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_IncomingLineSideLibrary_4(BMSEmployee wLoginUser, int wBatchDemandID,
                                                                WMSBatchPickDemandItem wWMSBatchPickDemandItem,
                                                                WMSBatchPickDemandItemStock wWMSBatchPickDemandItemStock) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            WMSBatchPickDemand wWMSBatchPickDemand = WMSBatchPickDemandDAO.getInstance().SelectByID(wLoginUser,
                    wBatchDemandID, wErrorCode);
            if (wWMSBatchPickDemand == null || wWMSBatchPickDemand.ID <= 0 || wWMSBatchPickDemand.ItemList == null
                    || wWMSBatchPickDemand.ItemList.size() <= 0) {
                return wResult;
            }

            SFCBatchBOMTaskBPM wSFCBatchBOMTaskBPM = SFCBatchBOMTaskBPMDAO.getInstance().SelectByID(wLoginUser,
                    wWMSBatchPickDemand.SourceID, wErrorCode);
            if (wSFCBatchBOMTaskBPM == null || wSFCBatchBOMTaskBPM.ID <= 0
                    || wSFCBatchBOMTaskBPM.SFCBatchBOMTaskBPMItemList == null
                    || wSFCBatchBOMTaskBPM.SFCBatchBOMTaskBPMItemList.size() <= 0) {
                return wResult;
            }

            List<SFCBatchBOMTaskBPMItem> wItemList = wSFCBatchBOMTaskBPM.SFCBatchBOMTaskBPMItemList;

            // 获取工区工位字典
            Map<Integer, Integer> wPartAreaMap = WMSBatchPickDemandDAO.getInstance().GetPartAreaMap(wLoginUser,
                    wErrorCode);
            // 物料分工区进行分配
            List<WMSBatchPickDemandItem> wWMSBatchPickDemandItemList = wWMSBatchPickDemand.ItemList.stream()
                    .filter(p -> p.PickedNumber > 0).collect(Collectors.toList());

            Calendar wBaseTime = Calendar.getInstance();
            wBaseTime.set(2000, 0, 1, 0, 0, 0);
            // 分批次入线边库
            this.InstockByBatchNumber(wLoginUser, wWMSBatchPickDemandItem, wItemList, wPartAreaMap,
                    wWMSBatchPickDemandItemStock, wErrorCode);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<String> WMS_ExportUseList(BMSEmployee wLoginUser, int wProductID, int wLineID,
                                                   int wCustomerID, String wOrderIDs, int wPartID, int wPartPointID,
                                                   String wMaterial, int wAreaID, int wIsPost,
                                                   String wBatchNumber, Calendar wStartTime, Calendar wEndTime,
                                                   String wPostMsgLike) {
        ServiceResult<String> wResult = new ServiceResult<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSLineEdgeLibraryItem> wList = WMSLineEdgeLibraryItemDAO.getInstance().SelectListByPage(wLoginUser,
                    wProductID, wLineID, wCustomerID, wOrderIDs, wPartID, wPartPointID, wMaterial, wAreaID, wIsPost,
                    wBatchNumber, wPostMsgLike,
                    wStartTime,
                    wEndTime, Pagination.getMaxSize(),
                    wErrorCode);

            MyExcelSheet wMyExcelSheet = WMSLineEdgeLibraryItemDAO.getInstance().GetMyExcelSheet(wList);

            List<MyExcelSheet> wMyExcelSheetList = new ArrayList<MyExcelSheet>(
                    Collections.singletonList(wMyExcelSheet));

            wResult.Result = ExcelUtil.ExportData(wMyExcelSheetList, "物料使用明细台账");

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    // region 线边库修改2023-11-20 09:44:23

    @Override
    public ServiceResult<Integer> WMS_BatchReservedPosting(BMSEmployee wLoginUser,
                                                           List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            for (WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem : wWMSLineEdgeLibraryItemList) {
                WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_BatchReservedPostingByCondition(BMSEmployee wLoginUser, int wProductID,
                                                                      int wLineID, int wCustomerID, String wOrderIDs,
                                                                      int wPartID, int wPartPointID,
                                                                      String wMaterial, int wAreaID,
                                                                      int wIsPost, String wBatchNumber,
                                                                      Calendar wStartTime, Calendar wEndTime,
                                                                      String wPostMsgLike, int wIsPostSetValue) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList = WMSLineEdgeLibraryItemDAO.getInstance()
                    .SelectListByPage(wLoginUser, wProductID, wLineID, wCustomerID, wOrderIDs, wPartID, wPartPointID,
                            wMaterial, wAreaID, wIsPost, wBatchNumber,
                            wPostMsgLike,
                            wStartTime,
                            wEndTime, Pagination.getMaxSize(),
                            wErrorCode);
            for (WMSLineEdgeLibraryItem wWMSLineEdgeLibraryItem : wWMSLineEdgeLibraryItemList) {
                wWMSLineEdgeLibraryItem.IsPost = wIsPostSetValue;
                WMSLineEdgeLibraryItemDAO.getInstance().Update(wLoginUser, wWMSLineEdgeLibraryItem, wErrorCode);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> WMS_LineHandleData(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            List<Integer> wItemStockIDList = WMSLineEdgeLibraryDAO.getInstance().WMS_QueryToHandleDataList(wLoginUser,
                    wErrorCode);
            if (wItemStockIDList == null || wItemStockIDList.size() <= 0) {
                return wResult;
            }

            for (int wItemStockID : wItemStockIDList) {
                WMSPickDemandItemStock wWMSPickDemandItemStock = WMSPickDemandItemStockDAO.getInstance()
                        .SelectByID(wLoginUser, wItemStockID, wErrorCode);
                if (wWMSPickDemandItemStock == null || wWMSPickDemandItemStock.ID <= 0) {
                    continue;
                }

                WMSPickDemandItem wWMSPickDemandItem = WMSPickDemandItemDAO.getInstance().SelectByID(wLoginUser,
                        wWMSPickDemandItemStock.TaskID, wErrorCode);
                if (wWMSPickDemandItem == null || wWMSPickDemandItem.ID <= 0) {
                    continue;
                }

                WMSPickDemand wWMSPickDemand = WMSPickDemandDAO.getInstance().SelectByIDWithoutSub(wLoginUser,
                        wWMSPickDemandItem.DemandID, wErrorCode);
                if (wWMSPickDemand == null || wWMSPickDemand.ID <= 0) {
                    continue;
                }

                // ①查询线边库存中是否有消耗记录，若有，则不入线边库
                List<WMSLineEdgeLibraryItem> wWMSLineEdgeLibraryItemList = WMSLineEdgeLibraryItemDAO.getInstance()
                        .SelectList(wLoginUser, -1, -1, -1,
                                -1, -1, wWMSPickDemand.OrderID, wWMSPickDemand.PartID, wWMSPickDemandItem.PartPointID,
                                wWMSPickDemandItem.MaterialID, null, null, wErrorCode);
                if (wWMSLineEdgeLibraryItemList != null && wWMSLineEdgeLibraryItemList.size() > 0) {
                    continue;
                }

                // 重新入线边库
                MyHelperServiceImpl.getInstance().WMS_ReRecoilInstockLine(wLoginUser, wWMSPickDemand.ID,
                        wWMSPickDemandItem.ID, wItemStockID);
            }

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }

    // endregion

    @Override
    public ServiceResult<Integer> WMS_TechChangeByOrders(BMSEmployee wLoginUser, int wTechChangeNoticeID,
                                                         String wOrderIDs) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // 查询工艺变更通知单
            TCMTechChangeNotice wTCMTechChangeNotice = QMSServiceImpl.getInstance()
                    .TCM_QueryTechChangeNotice(wLoginUser, wTechChangeNoticeID).Info(TCMTechChangeNotice.class);
            if (wTCMTechChangeNotice == null || wTCMTechChangeNotice.ID <= 0) {
                logger.info("工艺变更通知单查询失败，ID：" + wTechChangeNoticeID + "不存在!");
                return wResult;
            }
            // 筛选订单
            List<Integer> wOrderIDList = StringUtils.parseIntList(wOrderIDs.split(","));
            wTCMTechChangeNotice.OrderList = wTCMTechChangeNotice.OrderList.stream()
                    .filter(p -> wOrderIDList.stream().anyMatch(q -> q.intValue() == p.intValue()))
                    .collect(Collectors.toList());
            // 查询变更明细
            TCMMaterialChangeLog wTCMMaterialChangeLog = QMSServiceImpl.getInstance()
                    .TCM_QueryMaterialChangeLog(wLoginUser,
                            wTCMTechChangeNotice.ChangeLogID)
                    .Custom("list", TCMMaterialChangeLog.class);
            if (wTCMMaterialChangeLog == null || wTCMMaterialChangeLog.ID <= 0 || wTCMMaterialChangeLog.ItemList == null
                    || wTCMMaterialChangeLog.ItemList.size() <= 0) {
                logger.info("物料变更明细查询失败，明细头ID：" + wTCMTechChangeNotice.ChangeLogID + "不存在!");
                return wResult;
            }
            // 调用工艺变更接口
            WMSServiceImpl.getInstance().WMS_TechChange(wLoginUser, wTCMTechChangeNotice,
                    wTCMMaterialChangeLog.ItemList);

            wResult.setFaultCode(MESException.getEnumType(wErrorCode.Result).getLable());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }
}
